28
28
import javax .servlet .http .HttpServletRequest ;
29
29
import javax .servlet .http .HttpServletResponse ;
30
30
31
+ import org .springframework .core .GenericTypeResolver ;
31
32
import org .springframework .core .MethodParameter ;
32
33
import org .springframework .core .ParameterizedTypeReference ;
33
34
import org .springframework .core .ResolvableType ;
59
60
import org .springframework .web .util .UrlPathHelper ;
60
61
61
62
/**
62
- * Extends {@link AbstractMessageConverterMethodArgumentResolver} with the ability to handle
63
- * method return values by writing to the response with {@link HttpMessageConverter HttpMessageConverters}.
63
+ * Extends {@link AbstractMessageConverterMethodArgumentResolver} with the ability to handle method
64
+ * return values by writing to the response with {@link HttpMessageConverter HttpMessageConverters}.
64
65
*
65
66
* @author Arjen Poutsma
66
67
* @author Rossen Stoyanchev
67
68
* @author Brian Clozel
69
+ * @author Juergen Hoeller
68
70
* @since 3.1
69
71
*/
70
72
public abstract class AbstractMessageConverterMethodProcessor extends AbstractMessageConverterMethodArgumentResolver
@@ -180,30 +182,30 @@ protected <T> void writeWithMessageConverters(@Nullable T value, MethodParameter
180
182
181
183
Object body ;
182
184
Class <?> valueType ;
183
- Type declaredType ;
185
+ Type targetType ;
184
186
185
187
if (value instanceof CharSequence ) {
186
188
body = value .toString ();
187
189
valueType = String .class ;
188
- declaredType = String .class ;
190
+ targetType = String .class ;
189
191
}
190
192
else {
191
193
body = value ;
192
194
valueType = getReturnValueType (body , returnType );
193
- declaredType = getGenericType (returnType );
195
+ targetType = GenericTypeResolver . resolveType ( getGenericType (returnType ), returnType . getContainingClass () );
194
196
}
195
197
196
198
if (isResourceType (value , returnType )) {
197
199
outputMessage .getHeaders ().set (HttpHeaders .ACCEPT_RANGES , "bytes" );
198
- if (value != null && inputMessage .getHeaders ().getFirst (HttpHeaders .RANGE ) != null
199
- && outputMessage .getServletResponse ().getStatus () == 200 ) {
200
+ if (value != null && inputMessage .getHeaders ().getFirst (HttpHeaders .RANGE ) != null &&
201
+ outputMessage .getServletResponse ().getStatus () == 200 ) {
200
202
Resource resource = (Resource ) value ;
201
203
try {
202
204
List <HttpRange > httpRanges = inputMessage .getHeaders ().getRange ();
203
205
outputMessage .getServletResponse ().setStatus (HttpStatus .PARTIAL_CONTENT .value ());
204
206
body = HttpRange .toResourceRegions (httpRanges , resource );
205
207
valueType = body .getClass ();
206
- declaredType = RESOURCE_REGION_LIST_TYPE ;
208
+ targetType = RESOURCE_REGION_LIST_TYPE ;
207
209
}
208
210
catch (IllegalArgumentException ex ) {
209
211
outputMessage .getHeaders ().set (HttpHeaders .CONTENT_RANGE , "bytes */" + resource .contentLength ());
@@ -225,7 +227,7 @@ protected <T> void writeWithMessageConverters(@Nullable T value, MethodParameter
225
227
else {
226
228
HttpServletRequest request = inputMessage .getServletRequest ();
227
229
List <MediaType > requestedMediaTypes = getAcceptableMediaTypes (request );
228
- List <MediaType > producibleMediaTypes = getProducibleMediaTypes (request , valueType , declaredType );
230
+ List <MediaType > producibleMediaTypes = getProducibleMediaTypes (request , valueType , targetType );
229
231
230
232
if (body != null && producibleMediaTypes .isEmpty ()) {
231
233
throw new HttpMessageNotWritableException (
@@ -270,22 +272,22 @@ else if (mediaType.equals(MediaType.ALL) || mediaType.equals(MEDIA_TYPE_APPLICAT
270
272
if (selectedMediaType != null ) {
271
273
selectedMediaType = selectedMediaType .removeQualityValue ();
272
274
for (HttpMessageConverter <?> converter : this .messageConverters ) {
273
- GenericHttpMessageConverter genericConverter =
274
- (converter instanceof GenericHttpMessageConverter ? ( GenericHttpMessageConverter <?>) converter : null );
275
+ GenericHttpMessageConverter genericConverter = ( converter instanceof GenericHttpMessageConverter ?
276
+ (GenericHttpMessageConverter <?>) converter : null );
275
277
if (genericConverter != null ?
276
- ((GenericHttpMessageConverter ) converter ).canWrite (declaredType , valueType , selectedMediaType ) :
278
+ ((GenericHttpMessageConverter ) converter ).canWrite (targetType , valueType , selectedMediaType ) :
277
279
converter .canWrite (valueType , selectedMediaType )) {
278
280
body = getAdvice ().beforeBodyWrite (body , returnType , selectedMediaType ,
279
281
(Class <? extends HttpMessageConverter <?>>) converter .getClass (),
280
282
inputMessage , outputMessage );
281
283
if (body != null ) {
282
284
if (logger .isDebugEnabled ()) {
283
- Object formatted = body instanceof CharSequence ? "\" " + body + "\" " : body ;
285
+ Object formatted = ( body instanceof CharSequence ? "\" " + body + "\" " : body ) ;
284
286
logger .debug ("Writing [" + formatted + "]" );
285
287
}
286
288
addContentDispositionHeader (inputMessage , outputMessage );
287
289
if (genericConverter != null ) {
288
- genericConverter .write (body , declaredType , selectedMediaType , outputMessage );
290
+ genericConverter .write (body , targetType , selectedMediaType , outputMessage );
289
291
}
290
292
else {
291
293
((HttpMessageConverter ) converter ).write (body , selectedMediaType , outputMessage );
@@ -356,18 +358,19 @@ protected List<MediaType> getProducibleMediaTypes(HttpServletRequest request, Cl
356
358
* @since 4.2
357
359
*/
358
360
@ SuppressWarnings ("unchecked" )
359
- protected List <MediaType > getProducibleMediaTypes (HttpServletRequest request , Class <?> valueClass ,
360
- @ Nullable Type declaredType ) {
361
+ protected List <MediaType > getProducibleMediaTypes (
362
+ HttpServletRequest request , Class <?> valueClass , @ Nullable Type targetType ) {
361
363
362
- Set <MediaType > mediaTypes = (Set <MediaType >) request .getAttribute (HandlerMapping .PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE );
364
+ Set <MediaType > mediaTypes =
365
+ (Set <MediaType >) request .getAttribute (HandlerMapping .PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE );
363
366
if (!CollectionUtils .isEmpty (mediaTypes )) {
364
367
return new ArrayList <>(mediaTypes );
365
368
}
366
369
else if (!this .allSupportedMediaTypes .isEmpty ()) {
367
370
List <MediaType > result = new ArrayList <>();
368
371
for (HttpMessageConverter <?> converter : this .messageConverters ) {
369
- if (converter instanceof GenericHttpMessageConverter && declaredType != null ) {
370
- if (((GenericHttpMessageConverter <?>) converter ).canWrite (declaredType , valueClass , null )) {
372
+ if (converter instanceof GenericHttpMessageConverter && targetType != null ) {
373
+ if (((GenericHttpMessageConverter <?>) converter ).canWrite (targetType , valueClass , null )) {
371
374
result .addAll (converter .getSupportedMediaTypes ());
372
375
}
373
376
}
0 commit comments