1
1
/*
2
- * Copyright 2002-2021 the original author or authors.
2
+ * Copyright 2002-2022 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
33
33
import org .reactivestreams .Publisher ;
34
34
import reactor .core .publisher .Flux ;
35
35
import reactor .core .publisher .Mono ;
36
+ import reactor .util .context .ContextView ;
36
37
37
38
import org .springframework .core .MethodParameter ;
38
39
import org .springframework .core .ResolvableType ;
46
47
import org .springframework .http .codec .HttpMessageDecoder ;
47
48
import org .springframework .http .server .reactive .ServerHttpRequest ;
48
49
import org .springframework .http .server .reactive .ServerHttpResponse ;
49
- import org .springframework .lang .NonNull ;
50
50
import org .springframework .lang .Nullable ;
51
51
import org .springframework .util .Assert ;
52
52
import org .springframework .util .MimeType ;
@@ -139,22 +139,26 @@ public Flux<Object> decode(Publisher<DataBuffer> input, ResolvableType elementTy
139
139
Flux <TokenBuffer > tokens = Jackson2Tokenizer .tokenize (processed , mapper .getFactory (), mapper ,
140
140
true , forceUseOfBigDecimal , getMaxInMemorySize ());
141
141
142
- ObjectReader objectReader = getObjectReader (mapper , elementType , hints );
143
-
144
- return customizeReaderFromStream (objectReader , mimeType , elementType , hints )
145
- .flatMapMany (reader -> tokens .handle ((tokenBuffer , sink ) -> {
146
- try {
147
- Object value = reader .readValue (tokenBuffer .asParser (mapper ));
148
- logValue (value , hints );
149
- if (value != null ) {
150
- sink .next (value );
151
- }
152
- }
153
- catch (IOException ex ) {
154
- sink .error (processException (ex ));
155
- }
156
- })
157
- );
142
+ return Flux .deferContextual (contextView -> {
143
+
144
+ Map <String , Object > hintsToUse = contextView .isEmpty () ? hints :
145
+ Hints .merge (hints , ContextView .class .getName (), contextView );
146
+
147
+ ObjectReader reader = createObjectReader (mapper , elementType , hintsToUse );
148
+
149
+ return tokens .handle ((tokenBuffer , sink ) -> {
150
+ try {
151
+ Object value = reader .readValue (tokenBuffer .asParser (mapper ));
152
+ logValue (value , hints );
153
+ if (value != null ) {
154
+ sink .next (value );
155
+ }
156
+ }
157
+ catch (IOException ex ) {
158
+ sink .error (processException (ex ));
159
+ }
160
+ });
161
+ });
158
162
}
159
163
160
164
/**
@@ -169,45 +173,36 @@ public Flux<Object> decode(Publisher<DataBuffer> input, ResolvableType elementTy
169
173
* @since 5.1.14
170
174
*/
171
175
protected Flux <DataBuffer > processInput (Publisher <DataBuffer > input , ResolvableType elementType ,
172
- @ Nullable MimeType mimeType , @ Nullable Map <String , Object > hints ) {
176
+ @ Nullable MimeType mimeType , @ Nullable Map <String , Object > hints ) {
173
177
174
178
return Flux .from (input );
175
179
}
176
180
177
181
@ Override
178
182
public Mono <Object > decodeToMono (Publisher <DataBuffer > input , ResolvableType elementType ,
179
183
@ Nullable MimeType mimeType , @ Nullable Map <String , Object > hints ) {
180
- return DataBufferUtils .join (input , this .maxInMemorySize )
181
- .flatMap (dataBuffer -> {
182
- try {
183
- ObjectReader objectReader = getObjectReader (elementType , mimeType , hints );
184
- return customizeReaderFromStream (objectReader , mimeType , elementType , hints )
185
- .flatMap (reader -> {
186
- try {
187
- return Mono .justOrEmpty (decode (dataBuffer , reader , hints ));
188
- }
189
- catch (DecodingException ex ) {
190
- return Mono .error (ex );
191
- }
192
- });
193
- }
194
- catch (IllegalStateException ex ) {
195
- return Mono .error (ex );
196
- }
197
- });
184
+
185
+ return Mono .deferContextual (contextView -> {
186
+
187
+ Map <String , Object > hintsToUse = contextView .isEmpty () ? hints :
188
+ Hints .merge (hints , ContextView .class .getName (), contextView );
189
+
190
+ return DataBufferUtils .join (input , this .maxInMemorySize ).flatMap (dataBuffer ->
191
+ Mono .justOrEmpty (decode (dataBuffer , elementType , mimeType , hintsToUse )));
192
+ });
198
193
}
199
194
200
195
@ Override
201
196
public Object decode (DataBuffer dataBuffer , ResolvableType targetType ,
202
197
@ Nullable MimeType mimeType , @ Nullable Map <String , Object > hints ) throws DecodingException {
203
- ObjectReader reader = getObjectReader (targetType , mimeType , hints );
204
- reader = customizeReader (reader , mimeType , targetType , hints );
205
- return decode (dataBuffer , reader , hints );
206
- }
207
198
208
- private Object decode (@ NonNull DataBuffer dataBuffer , @ NonNull ObjectReader objectReader ,
209
- @ Nullable Map <String , Object > hints ) throws DecodingException {
199
+ ObjectMapper mapper = selectObjectMapper (targetType , mimeType );
200
+ if (mapper == null ) {
201
+ throw new IllegalStateException ("No ObjectMapper for " + targetType );
202
+ }
203
+
210
204
try {
205
+ ObjectReader objectReader = createObjectReader (mapper , targetType , hints );
211
206
Object value = objectReader .readValue (dataBuffer .asInputStream ());
212
207
logValue (value , hints );
213
208
return value ;
@@ -220,16 +215,7 @@ private Object decode(@NonNull DataBuffer dataBuffer, @NonNull ObjectReader obje
220
215
}
221
216
}
222
217
223
- private ObjectReader getObjectReader (ResolvableType targetType , @ Nullable MimeType mimeType ,
224
- @ Nullable Map <String , Object > hints ) {
225
- ObjectMapper mapper = selectObjectMapper (targetType , mimeType );
226
- if (mapper == null ) {
227
- throw new IllegalStateException ("No ObjectMapper for " + targetType );
228
- }
229
- return getObjectReader (mapper , targetType , hints );
230
- }
231
-
232
- private ObjectReader getObjectReader (
218
+ private ObjectReader createObjectReader (
233
219
ObjectMapper mapper , ResolvableType elementType , @ Nullable Map <String , Object > hints ) {
234
220
235
221
Assert .notNull (elementType , "'elementType' must not be null" );
@@ -239,34 +225,28 @@ private ObjectReader getObjectReader(
239
225
}
240
226
JavaType javaType = getJavaType (elementType .getType (), contextClass );
241
227
Class <?> jsonView = (hints != null ? (Class <?>) hints .get (Jackson2CodecSupport .JSON_VIEW_HINT ) : null );
242
- return jsonView != null ?
228
+
229
+ ObjectReader objectReader = (jsonView != null ?
243
230
mapper .readerWithView (jsonView ).forType (javaType ) :
244
- mapper .readerFor (javaType );
245
- }
231
+ mapper .readerFor (javaType ));
246
232
247
- /**
248
- * Provides the ability for subclasses to customize the {@link ObjectReader} for deserialization from a stream.
249
- * @param reader the {@link ObjectReader} available for customization
250
- * @param mimeType the MIME type associated with the input stream
251
- * @param elementType the expected type of elements in the output stream
252
- * @param hints additional information about how to do encode
253
- * @return the customized {@link ObjectReader}
254
- */
255
- protected Mono <ObjectReader > customizeReaderFromStream (@ NonNull ObjectReader reader , @ Nullable MimeType mimeType ,
256
- ResolvableType elementType , @ Nullable Map <String , Object > hints ) {
257
- return Mono .just (customizeReader (reader , mimeType , elementType , hints ));
233
+ return customizeReader (objectReader , elementType , hints );
258
234
}
259
235
260
236
/**
261
- * Provides the ability for subclasses to customize the {@link ObjectReader} for deserialization.
262
- * @param reader the {@link ObjectReader} available for customization
263
- * @param mimeType the MIME type associated with the input stream
264
- * @param elementType the expected type of elements in the output stream
265
- * @param hints additional information about how to do encode
266
- * @return the customized {@link ObjectReader}
237
+ * Subclasses can use this method to customize {@link ObjectReader} used
238
+ * for reading values.
239
+ * @param reader the reader instance to customize
240
+ * @param elementType the target type of element values to read to
241
+ * @param hints a map with serialization hints;
242
+ * the Reactor Context, when available, may be accessed under the key
243
+ * {@code ContextView.class.getName()}
244
+ * @return the customized {@code ObjectReader} to use
245
+ * @since 6.0
267
246
*/
268
- protected ObjectReader customizeReader (@ NonNull ObjectReader reader , @ Nullable MimeType mimeType ,
269
- ResolvableType elementType , @ Nullable Map <String , Object > hints ) {
247
+ protected ObjectReader customizeReader (
248
+ ObjectReader reader , ResolvableType elementType , @ Nullable Map <String , Object > hints ) {
249
+
270
250
return reader ;
271
251
}
272
252
@@ -312,10 +292,6 @@ public List<MimeType> getDecodableMimeTypes() {
312
292
return getMimeTypes ();
313
293
}
314
294
315
- @ Override
316
- public List <MimeType > getDecodableMimeTypes (ResolvableType targetType ) {
317
- return getMimeTypes (targetType );
318
- }
319
295
320
296
// Jackson2CodecSupport
321
297
0 commit comments