17
17
package org .springframework .integration .http .inbound ;
18
18
19
19
import java .io .IOException ;
20
+ import java .lang .reflect .Type ;
20
21
import java .util .ArrayList ;
21
22
import java .util .HashMap ;
22
23
import java .util .List ;
39
40
import org .springframework .http .MediaType ;
40
41
import org .springframework .http .RequestEntity ;
41
42
import org .springframework .http .converter .ByteArrayHttpMessageConverter ;
43
+ import org .springframework .http .converter .GenericHttpMessageConverter ;
42
44
import org .springframework .http .converter .HttpMessageConverter ;
43
45
import org .springframework .http .converter .ResourceHttpMessageConverter ;
44
46
import org .springframework .http .converter .StringHttpMessageConverter ;
93
95
* In a request-reply scenario, the reply Message's payload will be extracted prior
94
96
* to generating a response by default.
95
97
* To have the entire serialized Message available for the response, switch the
96
- * {@link # extractReplyPayload} value to {@code false}.
98
+ * {@code extractReplyPayload} value to {@code false}.
97
99
*
98
100
* @author Mark Fisher
99
101
* @author Oleg Zhurakousky
@@ -146,27 +148,21 @@ public HttpRequestHandlingEndpointSupport(boolean expectReply) {
146
148
stringHttpMessageConverter .setWriteAcceptCharset (false );
147
149
this .defaultMessageConverters .add (stringHttpMessageConverter );
148
150
this .defaultMessageConverters .add (new ResourceHttpMessageConverter ());
149
- SourceHttpMessageConverter <Source > sourceConverter = new SourceHttpMessageConverter <Source >();
151
+ SourceHttpMessageConverter <Source > sourceConverter = new SourceHttpMessageConverter <>();
150
152
this .defaultMessageConverters .add (sourceConverter );
151
153
if (jaxb2Present ) {
152
154
this .defaultMessageConverters .add (new Jaxb2RootElementHttpMessageConverter ());
153
- if (logger .isDebugEnabled ()) {
154
- logger .debug ("'Jaxb2RootElementHttpMessageConverter' was added to the 'defaultMessageConverters'." );
155
- }
155
+ logger .debug ("'Jaxb2RootElementHttpMessageConverter' was added to the 'defaultMessageConverters'." );
156
156
}
157
157
if (JacksonPresent .isJackson2Present ()) {
158
158
this .defaultMessageConverters .add (new MappingJackson2HttpMessageConverter ());
159
- if (logger .isDebugEnabled ()) {
160
- logger .debug ("'MappingJackson2HttpMessageConverter' was added to the 'defaultMessageConverters'." );
161
- }
159
+ logger .debug ("'MappingJackson2HttpMessageConverter' was added to the 'defaultMessageConverters'." );
162
160
}
163
161
if (romeToolsPresent ) {
164
162
this .defaultMessageConverters .add (new AtomFeedHttpMessageConverter ());
165
163
this .defaultMessageConverters .add (new RssChannelHttpMessageConverter ());
166
- if (logger .isDebugEnabled ()) {
167
- logger .debug ("'AtomFeedHttpMessageConverter' was added to the 'defaultMessageConverters'." );
168
- logger .debug ("'RssChannelHttpMessageConverter' was added to the 'defaultMessageConverters'." );
169
- }
164
+ logger .debug ("'AtomFeedHttpMessageConverter' was added to the 'defaultMessageConverters'." );
165
+ logger .debug ("'RssChannelHttpMessageConverter' was added to the 'defaultMessageConverters'." );
170
166
}
171
167
}
172
168
@@ -176,8 +172,9 @@ public HttpRequestHandlingEndpointSupport(boolean expectReply) {
176
172
* @param messageConverters The message converters.
177
173
*/
178
174
public void setMessageConverters (List <HttpMessageConverter <?>> messageConverters ) {
175
+ Assert .notNull (messageConverters , "'messageConverters' must not be null" );
179
176
Assert .noNullElements (messageConverters .toArray (), "'messageConverters' must not contain null entries" );
180
- List <HttpMessageConverter <?>> localConverters = new ArrayList <HttpMessageConverter <?> >(messageConverters );
177
+ List <HttpMessageConverter <?>> localConverters = new ArrayList <>(messageConverters );
181
178
if (this .mergeWithDefaultConverters ) {
182
179
localConverters .addAll (this .defaultMessageConverters );
183
180
this .convertersMerged = true ;
@@ -266,14 +263,13 @@ private Message<?> actualDoHandleRequest(HttpServletRequest servletRequest, Requ
266
263
267
264
this .activeCount .incrementAndGet ();
268
265
try {
269
- StandardEvaluationContext evaluationContext = this . createEvaluationContext ();
266
+ StandardEvaluationContext evaluationContext = createEvaluationContext ();
270
267
evaluationContext .setRootObject (httpEntity );
271
268
272
269
evaluationContext .setVariable ("requestAttributes" , RequestContextHolder .currentRequestAttributes ());
273
270
274
- MultiValueMap <String , String > requestParams = this . convertParameterMap (servletRequest .getParameterMap ());
271
+ MultiValueMap <String , String > requestParams = convertParameterMap (servletRequest .getParameterMap ());
275
272
evaluationContext .setVariable ("requestParams" , requestParams );
276
-
277
273
evaluationContext .setVariable ("requestHeaders" , new ServletServerHttpRequest (servletRequest ).getHeaders ());
278
274
279
275
Cookie [] requestCookies = servletRequest .getCookies ();
@@ -335,12 +331,16 @@ private Message<?> actualDoHandleRequest(HttpServletRequest servletRequest, Requ
335
331
AbstractIntegrationMessageBuilder <?> messageBuilder = null ;
336
332
337
333
if (payload instanceof Message <?>) {
338
- messageBuilder = this .getMessageBuilderFactory ().fromMessage ((Message <?>) payload )
339
- .copyHeadersIfAbsent (headers );
334
+ messageBuilder =
335
+ getMessageBuilderFactory ()
336
+ .fromMessage ((Message <?>) payload )
337
+ .copyHeadersIfAbsent (headers );
340
338
}
341
339
else {
342
340
Assert .state (payload != null , "payload cannot be null" );
343
- messageBuilder = this .getMessageBuilderFactory ().withPayload (payload ).copyHeaders (headers );
341
+ messageBuilder = getMessageBuilderFactory ()
342
+ .withPayload (payload )
343
+ .copyHeaders (headers );
344
344
}
345
345
346
346
HttpMethod method = httpEntity .getMethod ();
@@ -359,30 +359,24 @@ private Message<?> actualDoHandleRequest(HttpServletRequest servletRequest, Requ
359
359
Message <?> reply = null ;
360
360
if (this .expectReply ) {
361
361
try {
362
- reply = this . sendAndReceiveMessage (message );
362
+ reply = sendAndReceiveMessage (message );
363
363
}
364
364
catch (MessageTimeoutException e ) {
365
- if (getStatusCodeExpression () != null ) {
366
- reply = getMessageBuilderFactory ().withPayload (e .getMessage ())
367
- .setHeader (org .springframework .integration .http .HttpHeaders .STATUS_CODE ,
368
- evaluateHttpStatus (httpEntity ))
369
- .build ();
370
- }
371
- else {
372
- reply = getMessageBuilderFactory ().withPayload (e .getMessage ())
373
- .setHeader (org .springframework .integration .http .HttpHeaders .STATUS_CODE ,
374
- HttpStatus .INTERNAL_SERVER_ERROR )
375
- .build ();
376
- }
365
+ reply =
366
+ getMessageBuilderFactory ()
367
+ .withPayload (e .getMessage ())
368
+ .setHeader (org .springframework .integration .http .HttpHeaders .STATUS_CODE ,
369
+ evaluateHttpStatus (httpEntity ))
370
+ .build ();
377
371
}
378
372
}
379
373
else {
380
- this . send (message );
374
+ send (message );
381
375
}
382
376
return reply ;
383
377
}
384
378
finally {
385
- this . postProcessRequest (servletRequest );
379
+ postProcessRequest (servletRequest );
386
380
this .activeCount .decrementAndGet ();
387
381
}
388
382
}
@@ -391,7 +385,8 @@ private Message<?> createServiceUnavailableResponse() {
391
385
if (logger .isDebugEnabled ()) {
392
386
logger .debug ("Endpoint is stopped; returning status " + HttpStatus .SERVICE_UNAVAILABLE );
393
387
}
394
- return this .getMessageBuilderFactory ().withPayload ("Endpoint is stopped" )
388
+ return getMessageBuilderFactory ()
389
+ .withPayload ("Endpoint is stopped" )
395
390
.setHeader (org .springframework .integration .http .HttpHeaders .STATUS_CODE , HttpStatus .SERVICE_UNAVAILABLE )
396
391
.build ();
397
392
}
@@ -401,7 +396,7 @@ private Message<?> createServiceUnavailableResponse() {
401
396
* sets up the {@link ServletServerHttpResponse}.
402
397
* @param response The ServletServerHttpResponse.
403
398
* @param replyMessage The reply message.
404
- * @return The message payload (if {@link # extractReplyPayload}) otherwise the message.
399
+ * @return The message payload (if {@code extractReplyPayload}) otherwise the message.
405
400
*/
406
401
protected final Object setupResponseAndConvertReply (ServletServerHttpResponse response , Message <?> replyMessage ) {
407
402
getHeaderMapper ().fromHeaders (replyMessage .getHeaders (), response .getHeaders ());
@@ -461,7 +456,7 @@ private void postProcessRequest(HttpServletRequest request) {
461
456
* Converts a servlet request's parameterMap to a {@link MultiValueMap}.
462
457
*/
463
458
private MultiValueMap <String , String > convertParameterMap (Map <String , String []> parameterMap ) {
464
- MultiValueMap <String , String > convertedMap = new LinkedMultiValueMap <String , String >(parameterMap .size ());
459
+ MultiValueMap <String , String > convertedMap = new LinkedMultiValueMap <>(parameterMap .size ());
465
460
for (Map .Entry <String , String []> entry : parameterMap .entrySet ()) {
466
461
String [] values = entry .getValue ();
467
462
for (String value : values ) {
@@ -487,29 +482,37 @@ protected Object extractRequestBody(ServletServerHttpRequest request) throws IOE
487
482
contentType = MediaType .APPLICATION_OCTET_STREAM ;
488
483
}
489
484
ResolvableType requestPayloadType = getRequestPayloadType ();
490
- Class <?> expectedType ;
491
485
if (requestPayloadType == null ) {
492
- expectedType = "text" .equals (contentType .getType ()) ? String .class : byte [].class ;
493
- }
494
- else {
495
- expectedType = requestPayloadType .resolve ();
486
+ requestPayloadType =
487
+ ResolvableType .forClass (
488
+ "text" .equals (contentType .getType ())
489
+ ? String .class
490
+ : byte [].class );
496
491
}
497
492
498
- /*
499
- * TODO: resolve() can return null, which is not valid for canRead().
500
- * Perhaps we should coerce to String/byte[] instead of attempting
501
- * to convert. However this might be a breaking change - 5.2?
502
- * Hence NOSONAR below.
503
- */
493
+ Type targetType = requestPayloadType .getType ();
494
+ Class <?> targetClass = requestPayloadType .toClass ();
495
+
504
496
for (HttpMessageConverter <?> converter : this .messageConverters ) {
505
- if (converter .canRead (expectedType , contentType )) {
506
- return converter .read ((Class ) expectedType , request );
497
+ GenericHttpMessageConverter <?> genericConverter =
498
+ converter instanceof GenericHttpMessageConverter
499
+ ? (GenericHttpMessageConverter <?>) converter
500
+ : null ;
501
+ if (genericConverter != null
502
+ ? genericConverter .canRead (targetType , null , contentType ) :
503
+ (converter .canRead (targetClass , contentType ))) {
504
+
505
+ if (genericConverter != null ) {
506
+ return genericConverter .read (targetType , null , request );
507
+ }
508
+ else {
509
+ return converter .read ((Class ) targetClass , request );
510
+ }
507
511
}
508
512
}
509
- throw new MessagingException (// NOSONAR might be null; see comment above.
513
+ throw new MessagingException (
510
514
"Could not convert request: no suitable HttpMessageConverter found for expected type ["
511
- + expectedType != null ? expectedType .getName () : "null"
512
- + "] and content type [" + contentType + "]" );
515
+ + requestPayloadType + "] and content type [" + contentType + "]" );
513
516
}
514
517
515
518
}
0 commit comments