From 1291d6e1bd5ba6524c3fb68813aad807d123c2e1 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Thu, 4 Feb 2016 23:55:48 -0500 Subject: [PATCH] Support CharSequence for response body Issue: SPR-13423 --- ...stractMessageConverterMethodProcessor.java | 7 ++++ .../HttpEntityMethodProcessorTests.java | 35 +++++++++++++++++-- ...questResponseBodyMethodProcessorTests.java | 25 ++++++++++++- 3 files changed, 63 insertions(+), 4 deletions(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodProcessor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodProcessor.java index f4034995041..98a55ac4935 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodProcessor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodProcessor.java @@ -170,6 +170,13 @@ public abstract class AbstractMessageConverterMethodProcessor extends AbstractMe Class returnValueClass = getReturnValueType(returnValue, returnType); Type returnValueType = getGenericType(returnType); + + if (returnValue != null && returnValue instanceof CharSequence) { + returnValueClass = String.class; + returnValueType = String.class; + returnValue = (T) returnValue.toString(); + } + HttpServletRequest servletRequest = inputMessage.getServletRequest(); List requestedMediaTypes = getAcceptableMediaTypes(servletRequest); List producibleMediaTypes = getProducibleMediaTypes(servletRequest, returnValueClass, returnValueType); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessorTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessorTests.java index 812592dea4b..b9f2abd70f9 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessorTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/HttpEntityMethodProcessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,6 @@ package org.springframework.web.servlet.mvc.method.annotation; import java.io.Serializable; import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -31,7 +30,10 @@ import org.junit.Test; import org.springframework.core.MethodParameter; import org.springframework.http.HttpEntity; import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.ByteArrayHttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.mock.web.test.MockHttpServletRequest; import org.springframework.mock.web.test.MockHttpServletResponse; @@ -45,7 +47,10 @@ import org.springframework.web.context.request.ServletWebRequest; import org.springframework.web.method.HandlerMethod; import org.springframework.web.method.support.ModelAndViewContainer; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; /** * Test fixture with {@link HttpEntityMethodProcessor} delegating to @@ -182,11 +187,35 @@ public class HttpEntityMethodProcessorTests { assertTrue(content.contains("\"type\":\"bar\"")); } + // SPR-13423 + + @Test + public void handleReturnValueCharSequence() throws Exception { + List>converters = new ArrayList<>(); + converters.add(new ByteArrayHttpMessageConverter()); + converters.add(new StringHttpMessageConverter()); + + Method method = getClass().getDeclaredMethod("handle"); + MethodParameter returnType = new MethodParameter(method, -1); + ResponseEntity returnValue = ResponseEntity.ok(new StringBuilder("Foo")); + + HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor(converters); + processor.handleReturnValue(returnValue, returnType, mavContainer, webRequest); + + assertEquals("text/plain;charset=ISO-8859-1", servletResponse.getHeader("Content-Type")); + assertEquals("Foo", servletResponse.getContentAsString()); + } + + @SuppressWarnings("unused") public void handle(HttpEntity> arg1, HttpEntity arg2) { } + ResponseEntity handle() { + return null; + } + @SuppressWarnings("unused") private static abstract class MyParameterizedController { diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java index 32ddb8bdd94..fda1ab263fe 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -290,6 +290,24 @@ public class RequestResponseBodyMethodProcessorTests { assertEquals("Foo", servletResponse.getContentAsString()); } + // SPR-13423 + + @Test + public void handleReturnValueCharSequence() throws Exception { + List>converters = new ArrayList<>(); + converters.add(new ByteArrayHttpMessageConverter()); + converters.add(new StringHttpMessageConverter()); + + Method method = ResponseBodyController.class.getMethod("handleWithCharSequence"); + MethodParameter returnType = new MethodParameter(method, -1); + + RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters); + processor.handleReturnValue(new StringBuilder("Foo"), returnType, mavContainer, webRequest); + + assertEquals("text/plain;charset=ISO-8859-1", servletResponse.getHeader("Content-Type")); + assertEquals("Foo", servletResponse.getContentAsString()); + } + @Test public void handleReturnValueStringAcceptCharset() throws Exception { this.servletRequest.addHeader("Accept", "text/plain;charset=UTF-8"); @@ -739,6 +757,11 @@ public class RequestResponseBodyMethodProcessorTests { public String handle() { return "hello"; } + + @RequestMapping + public CharSequence handleWithCharSequence() { + return null; + } }