001/* 002 * Copyright 2002-2020 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.http.codec; 018 019import java.util.List; 020import java.util.function.Consumer; 021 022import org.springframework.core.codec.Decoder; 023import org.springframework.core.codec.Encoder; 024import org.springframework.lang.Nullable; 025 026/** 027 * Defines a common interface for configuring either client or server HTTP 028 * message readers and writers. This is used as follows: 029 * <ul> 030 * <li>Use {@link ClientCodecConfigurer#create()} or 031 * {@link ServerCodecConfigurer#create()} to create an instance. 032 * <li>Use {@link #defaultCodecs()} to customize HTTP message readers or writers 033 * registered by default. 034 * <li>Use {@link #customCodecs()} to add custom HTTP message readers or writers. 035 * <li>Use {@link #getReaders()} and {@link #getWriters()} to obtain the list of 036 * configured HTTP message readers and writers. 037 * </ul> 038 * 039 * <p>HTTP message readers and writers are divided into 3 categories that are 040 * ordered as follows: 041 * <ol> 042 * <li>Typed readers and writers that support specific types, e.g. byte[], String. 043 * <li>Object readers and writers, e.g. JSON, XML. 044 * <li>Catch-all readers or writers, e.g. String with any media type. 045 * </ol> 046 * 047 * <p>Typed and object readers are further sub-divided and ordered as follows: 048 * <ol> 049 * <li>Default HTTP reader and writer registrations. 050 * <li>Custom readers and writers. 051 * </ol> 052 * 053 * @author Rossen Stoyanchev 054 * @since 5.0 055 */ 056public interface CodecConfigurer { 057 058 /** 059 * Provides a way to customize or replace HTTP message readers and writers 060 * registered by default. 061 * @see #registerDefaults(boolean) 062 */ 063 DefaultCodecs defaultCodecs(); 064 065 /** 066 * Register custom HTTP message readers or writers in addition to the ones 067 * registered by default. 068 */ 069 CustomCodecs customCodecs(); 070 071 /** 072 * Provides a way to completely turn off registration of default HTTP message 073 * readers and writers, and instead rely only on the ones provided via 074 * {@link #customCodecs()}. 075 * <p>By default this is set to {@code "true"} in which case default 076 * registrations are made; setting this to {@code false} disables default 077 * registrations. 078 */ 079 void registerDefaults(boolean registerDefaults); 080 081 082 /** 083 * Obtain the configured HTTP message readers. 084 */ 085 List<HttpMessageReader<?>> getReaders(); 086 087 /** 088 * Obtain the configured HTTP message writers. 089 */ 090 List<HttpMessageWriter<?>> getWriters(); 091 092 /** 093 * Create a copy of this {@link CodecConfigurer}. The returned clone has its 094 * own lists of default and custom codecs and generally can be configured 095 * independently. Keep in mind however that codec instances (if any are 096 * configured) are themselves not cloned. 097 * @since 5.1.12 098 */ 099 CodecConfigurer clone(); 100 101 102 /** 103 * Customize or replace the HTTP message readers and writers registered by 104 * default. The options are further extended by 105 * {@link ClientCodecConfigurer.ClientDefaultCodecs ClientDefaultCodecs} and 106 * {@link ServerCodecConfigurer.ServerDefaultCodecs ServerDefaultCodecs}. 107 */ 108 interface DefaultCodecs { 109 110 /** 111 * Override the default Jackson JSON {@code Decoder}. 112 * <p>Note that {@link #maxInMemorySize(int)}, if configured, will be 113 * applied to the given decoder. 114 * @param decoder the decoder instance to use 115 * @see org.springframework.http.codec.json.Jackson2JsonDecoder 116 */ 117 void jackson2JsonDecoder(Decoder<?> decoder); 118 119 /** 120 * Override the default Jackson JSON {@code Encoder}. 121 * @param encoder the encoder instance to use 122 * @see org.springframework.http.codec.json.Jackson2JsonEncoder 123 */ 124 void jackson2JsonEncoder(Encoder<?> encoder); 125 126 /** 127 * Override the default Jackson Smile {@code Decoder}. 128 * <p>Note that {@link #maxInMemorySize(int)}, if configured, will be 129 * applied to the given decoder. 130 * @param decoder the decoder instance to use 131 * @see org.springframework.http.codec.json.Jackson2SmileDecoder 132 */ 133 void jackson2SmileDecoder(Decoder<?> decoder); 134 135 /** 136 * Override the default Jackson Smile {@code Encoder}. 137 * @param encoder the encoder instance to use 138 * @see org.springframework.http.codec.json.Jackson2SmileEncoder 139 */ 140 void jackson2SmileEncoder(Encoder<?> encoder); 141 142 /** 143 * Override the default Protobuf {@code Decoder}. 144 * <p>Note that {@link #maxInMemorySize(int)}, if configured, will be 145 * applied to the given decoder. 146 * @param decoder the decoder instance to use 147 * @since 5.1 148 * @see org.springframework.http.codec.protobuf.ProtobufDecoder 149 */ 150 void protobufDecoder(Decoder<?> decoder); 151 152 /** 153 * Override the default Protobuf {@code Encoder}. 154 * @param encoder the encoder instance to use 155 * @since 5.1 156 * @see org.springframework.http.codec.protobuf.ProtobufEncoder 157 * @see org.springframework.http.codec.protobuf.ProtobufHttpMessageWriter 158 */ 159 void protobufEncoder(Encoder<?> encoder); 160 161 /** 162 * Override the default JAXB2 {@code Decoder}. 163 * <p>Note that {@link #maxInMemorySize(int)}, if configured, will be 164 * applied to the given decoder. 165 * @param decoder the decoder instance to use 166 * @since 5.1.3 167 * @see org.springframework.http.codec.xml.Jaxb2XmlDecoder 168 */ 169 void jaxb2Decoder(Decoder<?> decoder); 170 171 /** 172 * Override the default JABX2 {@code Encoder}. 173 * @param encoder the encoder instance to use 174 * @since 5.1.3 175 * @see org.springframework.http.codec.xml.Jaxb2XmlEncoder 176 */ 177 void jaxb2Encoder(Encoder<?> encoder); 178 179 /** 180 * Configure a limit on the number of bytes that can be buffered whenever 181 * the input stream needs to be aggregated. This can be a result of 182 * decoding to a single {@code DataBuffer}, 183 * {@link java.nio.ByteBuffer ByteBuffer}, {@code byte[]}, 184 * {@link org.springframework.core.io.Resource Resource}, {@code String}, etc. 185 * It can also occur when splitting the input stream, e.g. delimited text, 186 * in which case the limit applies to data buffered between delimiters. 187 * <p>By default this is not set, in which case individual codec defaults 188 * apply. All codecs are limited to 256K by default. 189 * @param byteCount the max number of bytes to buffer, or -1 for unlimited 190 * @since 5.1.11 191 */ 192 void maxInMemorySize(int byteCount); 193 194 /** 195 * Whether to log form data at DEBUG level, and headers at TRACE level. 196 * Both may contain sensitive information. 197 * <p>By default set to {@code false} so that request details are not shown. 198 * @param enable whether to enable or not 199 * @since 5.1 200 */ 201 void enableLoggingRequestDetails(boolean enable); 202 } 203 204 205 /** 206 * Registry for custom HTTP message readers and writers. 207 */ 208 interface CustomCodecs { 209 210 /** 211 * Register a custom codec. This is expected to be one of the following: 212 * <ul> 213 * <li>{@link HttpMessageReader} 214 * <li>{@link HttpMessageWriter} 215 * <li>{@link Encoder} (wrapped internally with {@link EncoderHttpMessageWriter}) 216 * <li>{@link Decoder} (wrapped internally with {@link DecoderHttpMessageReader}) 217 * </ul> 218 * @param codec the codec to register 219 * @since 5.1.13 220 */ 221 void register(Object codec); 222 223 /** 224 * Variant of {@link #register(Object)} that also applies the below 225 * properties, if configured, via {@link #defaultCodecs()}: 226 * <ul> 227 * <li>{@link CodecConfigurer.DefaultCodecs#maxInMemorySize(int) maxInMemorySize} 228 * <li>{@link CodecConfigurer.DefaultCodecs#enableLoggingRequestDetails(boolean) enableLoggingRequestDetails} 229 * </ul> 230 * <p>The properties are applied every time {@link #getReaders()} or 231 * {@link #getWriters()} are used to obtain the list of configured 232 * readers or writers. 233 * @param codec the codec to register and apply default config to 234 * @since 5.1.13 235 */ 236 void registerWithDefaultConfig(Object codec); 237 238 /** 239 * Variant of {@link #register(Object)} that also allows the caller to 240 * apply the properties from {@link DefaultCodecConfig} to the given 241 * codec. If you want to apply all the properties, prefer using 242 * {@link #registerWithDefaultConfig(Object)}. 243 * <p>The consumer is called every time {@link #getReaders()} or 244 * {@link #getWriters()} are used to obtain the list of configured 245 * readers or writers. 246 * @param codec the codec to register 247 * @param configConsumer consumer of the default config 248 * @since 5.1.13 249 */ 250 void registerWithDefaultConfig(Object codec, Consumer<DefaultCodecConfig> configConsumer); 251 252 /** 253 * Add a custom {@code Decoder} internally wrapped with 254 * {@link DecoderHttpMessageReader}). 255 * @param decoder the decoder to add 256 * @deprecated as of 5.1.13, use {@link #register(Object)} or 257 * {@link #registerWithDefaultConfig(Object)} instead. 258 */ 259 @Deprecated 260 void decoder(Decoder<?> decoder); 261 262 /** 263 * Add a custom {@code Encoder}, internally wrapped with 264 * {@link EncoderHttpMessageWriter}. 265 * @param encoder the encoder to add 266 * @deprecated as of 5.1.13, use {@link #register(Object)} or 267 * {@link #registerWithDefaultConfig(Object)} instead. 268 */ 269 @Deprecated 270 void encoder(Encoder<?> encoder); 271 272 /** 273 * Add a custom {@link HttpMessageReader}. For readers of type 274 * {@link DecoderHttpMessageReader} consider using the shortcut 275 * {@link #decoder(Decoder)} instead. 276 * @param reader the reader to add 277 * @deprecated as of 5.1.13, use {@link #register(Object)} or 278 * {@link #registerWithDefaultConfig(Object)} instead. 279 */ 280 @Deprecated 281 void reader(HttpMessageReader<?> reader); 282 283 /** 284 * Add a custom {@link HttpMessageWriter}. For writers of type 285 * {@link EncoderHttpMessageWriter} consider using the shortcut 286 * {@link #encoder(Encoder)} instead. 287 * @param writer the writer to add 288 * @deprecated as of 5.1.13, use {@link #register(Object)} or 289 * {@link #registerWithDefaultConfig(Object)} instead. 290 */ 291 @Deprecated 292 void writer(HttpMessageWriter<?> writer); 293 294 /** 295 * Register a callback for the {@link DefaultCodecConfig configuration} 296 * applied to default codecs. This allows custom codecs to follow general 297 * guidelines applied to default ones, such as logging details and limiting 298 * the amount of buffered data. 299 * @param codecsConfigConsumer the default codecs configuration callback 300 * @deprecated as of 5.1.13, use {@link #registerWithDefaultConfig(Object)} 301 * or {@link #registerWithDefaultConfig(Object, Consumer)} instead. 302 */ 303 @Deprecated 304 void withDefaultCodecConfig(Consumer<DefaultCodecConfig> codecsConfigConsumer); 305 } 306 307 308 /** 309 * Exposes the values of properties configured through 310 * {@link #defaultCodecs()} that are applied to default codecs. 311 * The main purpose of this interface is to provide access to them so they 312 * can also be applied to custom codecs if needed. 313 * @since 5.1.12 314 * @see CustomCodecs#registerWithDefaultConfig(Object, Consumer) 315 */ 316 interface DefaultCodecConfig { 317 318 /** 319 * Get the configured limit on the number of bytes that can be buffered whenever 320 * the input stream needs to be aggregated. 321 */ 322 @Nullable 323 Integer maxInMemorySize(); 324 325 /** 326 * Whether to log form data at DEBUG level, and headers at TRACE level. 327 * Both may contain sensitive information. 328 */ 329 @Nullable 330 Boolean isEnableLoggingRequestDetails(); 331 } 332 333}