|
|
|
@ -22,9 +22,7 @@ import java.io.Serializable;
|
|
|
|
|
import java.lang.reflect.Method;
|
|
|
|
|
import java.lang.reflect.Type;
|
|
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.Arrays;
|
|
|
|
|
import java.util.Collections;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
|
|
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
|
|
|
@ -32,8 +30,9 @@ import com.fasterxml.jackson.annotation.JsonTypeName;
|
|
|
|
|
import com.fasterxml.jackson.annotation.JsonView;
|
|
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
|
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
|
|
|
|
import org.junit.jupiter.api.BeforeEach;
|
|
|
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
|
import org.skyscreamer.jsonassert.JSONAssert;
|
|
|
|
|
import org.xmlunit.assertj.XmlAssert;
|
|
|
|
|
|
|
|
|
|
import org.springframework.aop.framework.ProxyFactory;
|
|
|
|
|
import org.springframework.aop.target.SingletonTargetSource;
|
|
|
|
@ -56,7 +55,9 @@ import org.springframework.http.converter.support.AllEncompassingFormHttpMessage
|
|
|
|
|
import org.springframework.http.converter.xml.MappingJackson2XmlHttpMessageConverter;
|
|
|
|
|
import org.springframework.lang.Nullable;
|
|
|
|
|
import org.springframework.util.MultiValueMap;
|
|
|
|
|
import org.springframework.util.ReflectionUtils;
|
|
|
|
|
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
|
|
|
|
import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
|
|
|
|
import org.springframework.web.accept.ContentNegotiationManagerFactoryBean;
|
|
|
|
|
import org.springframework.web.bind.WebDataBinder;
|
|
|
|
|
import org.springframework.web.bind.annotation.RequestBody;
|
|
|
|
@ -76,86 +77,63 @@ import org.springframework.web.util.WebUtils;
|
|
|
|
|
|
|
|
|
|
import static org.assertj.core.api.Assertions.assertThat;
|
|
|
|
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
|
|
|
|
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Test fixture for a {@link RequestResponseBodyMethodProcessor} with
|
|
|
|
|
* actual delegation to {@link HttpMessageConverter} instances. Also see
|
|
|
|
|
* {@link RequestResponseBodyMethodProcessorMockTests}.
|
|
|
|
|
* Tests for {@link RequestResponseBodyMethodProcessor} with actual delegation to
|
|
|
|
|
* {@link HttpMessageConverter} instances.
|
|
|
|
|
*
|
|
|
|
|
* @author Rossen Stoyanchev
|
|
|
|
|
* @author Sebastien Deleuze
|
|
|
|
|
* @author Sam Brannen
|
|
|
|
|
* @see RequestResponseBodyMethodProcessorMockTests
|
|
|
|
|
*/
|
|
|
|
|
@SuppressWarnings("unused")
|
|
|
|
|
public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
|
|
|
|
|
protected static final String NEWLINE_SYSTEM_PROPERTY = System.lineSeparator();
|
|
|
|
|
private final ModelAndViewContainer container = new ModelAndViewContainer();
|
|
|
|
|
|
|
|
|
|
private final MockHttpServletRequest servletRequest = new MockHttpServletRequest();
|
|
|
|
|
|
|
|
|
|
private ModelAndViewContainer container;
|
|
|
|
|
private final MockHttpServletResponse servletResponse = new MockHttpServletResponse();
|
|
|
|
|
|
|
|
|
|
private MockHttpServletRequest servletRequest;
|
|
|
|
|
private final NativeWebRequest request = new ServletWebRequest(servletRequest, servletResponse);
|
|
|
|
|
|
|
|
|
|
private MockHttpServletResponse servletResponse;
|
|
|
|
|
private final ValidatingBinderFactory factory = new ValidatingBinderFactory();
|
|
|
|
|
|
|
|
|
|
private NativeWebRequest request;
|
|
|
|
|
private final Method method = ReflectionUtils.findMethod(getClass(), "handle",
|
|
|
|
|
List.class, SimpleBean.class, MultiValueMap.class, String.class);
|
|
|
|
|
|
|
|
|
|
private ValidatingBinderFactory factory;
|
|
|
|
|
|
|
|
|
|
private MethodParameter paramGenericList;
|
|
|
|
|
private MethodParameter paramSimpleBean;
|
|
|
|
|
private MethodParameter paramMultiValueMap;
|
|
|
|
|
private MethodParameter paramString;
|
|
|
|
|
private MethodParameter returnTypeString;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@BeforeEach
|
|
|
|
|
public void setup() throws Exception {
|
|
|
|
|
container = new ModelAndViewContainer();
|
|
|
|
|
servletRequest = new MockHttpServletRequest();
|
|
|
|
|
servletRequest.setMethod("POST");
|
|
|
|
|
servletResponse = new MockHttpServletResponse();
|
|
|
|
|
request = new ServletWebRequest(servletRequest, servletResponse);
|
|
|
|
|
this.factory = new ValidatingBinderFactory();
|
|
|
|
|
|
|
|
|
|
Method method = getClass().getDeclaredMethod("handle",
|
|
|
|
|
List.class, SimpleBean.class, MultiValueMap.class, String.class);
|
|
|
|
|
paramGenericList = new MethodParameter(method, 0);
|
|
|
|
|
paramSimpleBean = new MethodParameter(method, 1);
|
|
|
|
|
paramMultiValueMap = new MethodParameter(method, 2);
|
|
|
|
|
paramString = new MethodParameter(method, 3);
|
|
|
|
|
returnTypeString = new MethodParameter(method, -1);
|
|
|
|
|
}
|
|
|
|
|
private final MethodParameter paramGenericList = new MethodParameter(method, 0);
|
|
|
|
|
private final MethodParameter paramSimpleBean = new MethodParameter(method, 1);
|
|
|
|
|
private final MethodParameter paramMultiValueMap = new MethodParameter(method, 2);
|
|
|
|
|
private final MethodParameter paramString = new MethodParameter(method, 3);
|
|
|
|
|
private final MethodParameter returnTypeString = new MethodParameter(method, -1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void resolveArgumentParameterizedType() throws Exception {
|
|
|
|
|
void resolveArgumentParameterizedType() throws Exception {
|
|
|
|
|
String content = "[{\"name\" : \"Jad\"}, {\"name\" : \"Robert\"}]";
|
|
|
|
|
this.servletRequest.setContent(content.getBytes(StandardCharsets.UTF_8));
|
|
|
|
|
this.servletRequest.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
|
|
|
|
converters.add(new MappingJackson2HttpMessageConverter());
|
|
|
|
|
List<HttpMessageConverter<?>> converters = List.of(new MappingJackson2HttpMessageConverter());
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
|
List<SimpleBean> result = (List<SimpleBean>) processor.resolveArgument(
|
|
|
|
|
paramGenericList, container, request, factory);
|
|
|
|
|
|
|
|
|
|
assertThat(result).isNotNull();
|
|
|
|
|
assertThat(result.get(0).getName()).isEqualTo("Jad");
|
|
|
|
|
assertThat(result.get(1).getName()).isEqualTo("Robert");
|
|
|
|
|
assertThat(result).map(SimpleBean::getName).containsExactly("Jad", "Robert");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void resolveArgumentRawTypeFromParameterizedType() throws Exception {
|
|
|
|
|
void resolveArgumentRawTypeFromParameterizedType() throws Exception {
|
|
|
|
|
String content = "fruit=apple&vegetable=kale";
|
|
|
|
|
this.servletRequest.setMethod("GET");
|
|
|
|
|
this.servletRequest.setContent(content.getBytes(StandardCharsets.UTF_8));
|
|
|
|
|
this.servletRequest.setContentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE);
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
|
|
|
|
converters.add(new AllEncompassingFormHttpMessageConverter());
|
|
|
|
|
List<HttpMessageConverter<?>> converters = List.of(new AllEncompassingFormHttpMessageConverter());
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
@ -168,13 +146,12 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void resolveArgumentClassJson() throws Exception {
|
|
|
|
|
void resolveArgumentClassJson() throws Exception {
|
|
|
|
|
String content = "{\"name\" : \"Jad\"}";
|
|
|
|
|
this.servletRequest.setContent(content.getBytes(StandardCharsets.UTF_8));
|
|
|
|
|
this.servletRequest.setContentType("application/json");
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
|
|
|
|
converters.add(new MappingJackson2HttpMessageConverter());
|
|
|
|
|
List<HttpMessageConverter<?>> converters = List.of(new MappingJackson2HttpMessageConverter());
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
|
|
|
|
|
|
|
|
|
|
SimpleBean result = (SimpleBean) processor.resolveArgument(
|
|
|
|
@ -185,47 +162,43 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void resolveArgumentClassString() throws Exception {
|
|
|
|
|
void resolveArgumentClassString() throws Exception {
|
|
|
|
|
String content = "foobarbaz";
|
|
|
|
|
this.servletRequest.setContent(content.getBytes(StandardCharsets.UTF_8));
|
|
|
|
|
this.servletRequest.setContentType("application/json");
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
|
|
|
|
converters.add(new StringHttpMessageConverter());
|
|
|
|
|
List<HttpMessageConverter<?>> converters = List.of(new StringHttpMessageConverter());
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
|
|
|
|
|
|
|
|
|
|
String result = (String) processor.resolveArgument(
|
|
|
|
|
paramString, container, request, factory);
|
|
|
|
|
|
|
|
|
|
assertThat(result).isNotNull();
|
|
|
|
|
assertThat(result).isEqualTo("foobarbaz");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test // SPR-9942
|
|
|
|
|
public void resolveArgumentRequiredNoContent() {
|
|
|
|
|
void resolveArgumentRequiredNoContent() {
|
|
|
|
|
this.servletRequest.setContent(new byte[0]);
|
|
|
|
|
this.servletRequest.setContentType("text/plain");
|
|
|
|
|
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
|
|
|
|
converters.add(new StringHttpMessageConverter());
|
|
|
|
|
List<HttpMessageConverter<?>> converters = List.of(new StringHttpMessageConverter());
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
|
|
|
|
|
assertThatExceptionOfType(HttpMessageNotReadableException.class).isThrownBy(() ->
|
|
|
|
|
processor.resolveArgument(paramString, container, request, factory));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test // SPR-12778
|
|
|
|
|
public void resolveArgumentRequiredNoContentDefaultValue() throws Exception {
|
|
|
|
|
void resolveArgumentRequiredNoContentDefaultValue() throws Exception {
|
|
|
|
|
this.servletRequest.setContent(new byte[0]);
|
|
|
|
|
this.servletRequest.setContentType("text/plain");
|
|
|
|
|
List<HttpMessageConverter<?>> converters = Collections.singletonList(new StringHttpMessageConverter());
|
|
|
|
|
List<Object> advice = Collections.singletonList(new EmptyRequestBodyAdvice());
|
|
|
|
|
List<HttpMessageConverter<?>> converters = List.of(new StringHttpMessageConverter());
|
|
|
|
|
List<Object> advice = List.of(new EmptyRequestBodyAdvice());
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters, advice);
|
|
|
|
|
String arg = (String) processor.resolveArgument(paramString, container, request, factory);
|
|
|
|
|
assertThat(arg).isNotNull();
|
|
|
|
|
assertThat(arg).isEqualTo("default value for empty body");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test // SPR-9964
|
|
|
|
|
public void resolveArgumentTypeVariable() throws Exception {
|
|
|
|
|
void resolveArgumentTypeVariable() throws Exception {
|
|
|
|
|
Method method = MyParameterizedController.class.getMethod("handleDto", Identifiable.class);
|
|
|
|
|
HandlerMethod handlerMethod = new HandlerMethod(new MySimpleParameterizedController(), method);
|
|
|
|
|
MethodParameter methodParam = handlerMethod.getMethodParameters()[0];
|
|
|
|
@ -234,8 +207,7 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
this.servletRequest.setContent(content.getBytes(StandardCharsets.UTF_8));
|
|
|
|
|
this.servletRequest.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
|
|
|
|
converters.add(new MappingJackson2HttpMessageConverter());
|
|
|
|
|
List<HttpMessageConverter<?>> converters = List.of(new MappingJackson2HttpMessageConverter());
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
|
|
|
|
|
|
|
|
|
|
SimpleBean result = (SimpleBean) processor.resolveArgument(methodParam, container, request, factory);
|
|
|
|
@ -245,7 +217,7 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test // SPR-14470
|
|
|
|
|
public void resolveParameterizedWithTypeVariableArgument() throws Exception {
|
|
|
|
|
void resolveParameterizedWithTypeVariableArgument() throws Exception {
|
|
|
|
|
Method method = MyParameterizedControllerWithList.class.getMethod("handleDto", List.class);
|
|
|
|
|
HandlerMethod handlerMethod = new HandlerMethod(new MySimpleParameterizedControllerWithList(), method);
|
|
|
|
|
MethodParameter methodParam = handlerMethod.getMethodParameters()[0];
|
|
|
|
@ -254,21 +226,18 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
this.servletRequest.setContent(content.getBytes(StandardCharsets.UTF_8));
|
|
|
|
|
this.servletRequest.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
|
|
|
|
converters.add(new MappingJackson2HttpMessageConverter());
|
|
|
|
|
List<HttpMessageConverter<?>> converters = List.of(new MappingJackson2HttpMessageConverter());
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
|
List<SimpleBean> result = (List<SimpleBean>) processor.resolveArgument(
|
|
|
|
|
methodParam, container, request, factory);
|
|
|
|
|
|
|
|
|
|
assertThat(result).isNotNull();
|
|
|
|
|
assertThat(result.get(0).getName()).isEqualTo("Jad");
|
|
|
|
|
assertThat(result.get(1).getName()).isEqualTo("Robert");
|
|
|
|
|
assertThat(result).map(SimpleBean::getName).containsExactly("Jad", "Robert");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test // SPR-11225
|
|
|
|
|
public void resolveArgumentTypeVariableWithNonGenericConverter() throws Exception {
|
|
|
|
|
void resolveArgumentTypeVariableWithNonGenericConverter() throws Exception {
|
|
|
|
|
Method method = MyParameterizedController.class.getMethod("handleDto", Identifiable.class);
|
|
|
|
|
HandlerMethod handlerMethod = new HandlerMethod(new MySimpleParameterizedController(), method);
|
|
|
|
|
MethodParameter methodParam = handlerMethod.getMethodParameters()[0];
|
|
|
|
@ -277,10 +246,9 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
this.servletRequest.setContent(content.getBytes(StandardCharsets.UTF_8));
|
|
|
|
|
this.servletRequest.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
|
|
|
|
HttpMessageConverter<Object> target = new MappingJackson2HttpMessageConverter();
|
|
|
|
|
HttpMessageConverter<?> proxy = ProxyFactory.getProxy(HttpMessageConverter.class, new SingletonTargetSource(target));
|
|
|
|
|
converters.add(proxy);
|
|
|
|
|
List<HttpMessageConverter<?>> converters = List.of(proxy);
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
|
|
|
|
|
|
|
|
|
|
SimpleBean result = (SimpleBean) processor.resolveArgument(methodParam, container, request, factory);
|
|
|
|
@ -290,12 +258,11 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test // SPR-9160
|
|
|
|
|
public void handleReturnValueSortByQuality() throws Exception {
|
|
|
|
|
void handleReturnValueSortByQuality() throws Exception {
|
|
|
|
|
this.servletRequest.addHeader("Accept", "text/plain; q=0.5, application/json");
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
|
|
|
|
converters.add(new MappingJackson2HttpMessageConverter());
|
|
|
|
|
converters.add(new StringHttpMessageConverter());
|
|
|
|
|
List<HttpMessageConverter<?>> converters =
|
|
|
|
|
List.of(new MappingJackson2HttpMessageConverter(), new StringHttpMessageConverter());
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
|
|
|
|
|
|
|
|
|
|
processor.writeWithMessageConverters("Foo", returnTypeString, request);
|
|
|
|
@ -304,11 +271,9 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void handleReturnValueString() throws Exception {
|
|
|
|
|
List<HttpMessageConverter<?>>converters = new ArrayList<>();
|
|
|
|
|
converters.add(new ByteArrayHttpMessageConverter());
|
|
|
|
|
converters.add(new StringHttpMessageConverter());
|
|
|
|
|
|
|
|
|
|
void handleReturnValueString() throws Exception {
|
|
|
|
|
List<HttpMessageConverter<?>> converters =
|
|
|
|
|
List.of(new ByteArrayHttpMessageConverter(), new StringHttpMessageConverter());
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
|
|
|
|
|
processor.handleReturnValue("Foo", returnTypeString, container, request);
|
|
|
|
|
|
|
|
|
@ -317,14 +282,12 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test // SPR-13423
|
|
|
|
|
public void handleReturnValueCharSequence() throws Exception {
|
|
|
|
|
List<HttpMessageConverter<?>>converters = new ArrayList<>();
|
|
|
|
|
converters.add(new ByteArrayHttpMessageConverter());
|
|
|
|
|
converters.add(new StringHttpMessageConverter());
|
|
|
|
|
|
|
|
|
|
void handleReturnValueCharSequence() throws Exception {
|
|
|
|
|
Method method = ResponseBodyController.class.getMethod("handleWithCharSequence");
|
|
|
|
|
MethodParameter returnType = new MethodParameter(method, -1);
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters =
|
|
|
|
|
List.of(new ByteArrayHttpMessageConverter(), new StringHttpMessageConverter());
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
|
|
|
|
|
processor.handleReturnValue(new StringBuilder("Foo"), returnType, container, request);
|
|
|
|
|
|
|
|
|
@ -333,12 +296,11 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void handleReturnValueStringAcceptCharset() throws Exception {
|
|
|
|
|
void handleReturnValueStringAcceptCharset() throws Exception {
|
|
|
|
|
this.servletRequest.addHeader("Accept", "text/plain;charset=UTF-8");
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
|
|
|
|
converters.add(new ByteArrayHttpMessageConverter());
|
|
|
|
|
converters.add(new StringHttpMessageConverter());
|
|
|
|
|
List<HttpMessageConverter<?>> converters =
|
|
|
|
|
List.of(new ByteArrayHttpMessageConverter(), new StringHttpMessageConverter());
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
|
|
|
|
|
|
|
|
|
|
processor.writeWithMessageConverters("Foo", returnTypeString, request);
|
|
|
|
@ -346,17 +308,14 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
assertThat(servletResponse.getHeader("Content-Type")).isEqualTo("text/plain;charset=UTF-8");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SPR-12894
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void handleReturnValueImage() throws Exception {
|
|
|
|
|
@Test // SPR-12894
|
|
|
|
|
void handleReturnValueImage() throws Exception {
|
|
|
|
|
this.servletRequest.addHeader("Accept", "*/*");
|
|
|
|
|
|
|
|
|
|
Method method = getClass().getDeclaredMethod("getImage");
|
|
|
|
|
MethodParameter returnType = new MethodParameter(method, -1);
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
|
|
|
|
converters.add(new ResourceHttpMessageConverter());
|
|
|
|
|
List<HttpMessageConverter<?>> converters = List.of(new ResourceHttpMessageConverter());
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
|
|
|
|
|
|
|
|
|
|
ClassPathResource resource = new ClassPathResource("logo.jpg", getClass());
|
|
|
|
@ -366,33 +325,29 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test // gh-26212
|
|
|
|
|
public void handleReturnValueWithObjectMapperByTypeRegistration() throws Exception {
|
|
|
|
|
void handleReturnValueWithObjectMapperByTypeRegistration() throws Exception {
|
|
|
|
|
MediaType halFormsMediaType = MediaType.parseMediaType("application/prs.hal-forms+json");
|
|
|
|
|
MediaType halMediaType = MediaType.parseMediaType("application/hal+json");
|
|
|
|
|
|
|
|
|
|
this.servletRequest.addHeader("Accept", halFormsMediaType + "," + halMediaType);
|
|
|
|
|
|
|
|
|
|
ObjectMapper objectMapper = new ObjectMapper();
|
|
|
|
|
objectMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
|
|
|
|
|
|
|
|
|
|
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
|
|
|
|
|
converter.registerObjectMappersForType(SimpleBean.class, map -> map.put(halMediaType, objectMapper));
|
|
|
|
|
|
|
|
|
|
this.servletRequest.addHeader("Accept", halFormsMediaType + "," + halMediaType);
|
|
|
|
|
|
|
|
|
|
SimpleBean simpleBean = new SimpleBean();
|
|
|
|
|
simpleBean.setId(12L);
|
|
|
|
|
simpleBean.setName("Jason");
|
|
|
|
|
|
|
|
|
|
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
|
|
|
|
|
converter.registerObjectMappersForType(SimpleBean.class, map -> map.put(halMediaType, objectMapper));
|
|
|
|
|
RequestResponseBodyMethodProcessor processor =
|
|
|
|
|
new RequestResponseBodyMethodProcessor(Collections.singletonList(converter));
|
|
|
|
|
new RequestResponseBodyMethodProcessor(List.of(converter));
|
|
|
|
|
MethodParameter returnType = new MethodParameter(getClass().getDeclaredMethod("getSimpleBean"), -1);
|
|
|
|
|
processor.writeWithMessageConverters(simpleBean, returnType, this.request);
|
|
|
|
|
|
|
|
|
|
assertThat(this.servletResponse.getHeader("Content-Type")).isEqualTo(halMediaType.toString());
|
|
|
|
|
assertThat(this.servletResponse.getContentAsString()).isEqualTo(
|
|
|
|
|
"{" + NEWLINE_SYSTEM_PROPERTY +
|
|
|
|
|
" \"id\" : 12," + NEWLINE_SYSTEM_PROPERTY +
|
|
|
|
|
" \"name\" : \"Jason\"" + NEWLINE_SYSTEM_PROPERTY +
|
|
|
|
|
"}");
|
|
|
|
|
JSONAssert.assertEquals("""
|
|
|
|
|
{ "id" : 12, "name" : "Jason" }""", this.servletResponse.getContentAsString(), true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
@ -419,7 +374,6 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void testProblemDetailMediaType(String expectedContentType) throws Exception {
|
|
|
|
|
|
|
|
|
|
ProblemDetail problemDetail = ProblemDetail.forStatus(HttpStatus.BAD_REQUEST);
|
|
|
|
|
|
|
|
|
|
this.servletRequest.setRequestURI("/path");
|
|
|
|
@ -437,20 +391,24 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
assertThat(this.servletResponse.getContentType()).isEqualTo(expectedContentType);
|
|
|
|
|
|
|
|
|
|
if (expectedContentType.equals(MediaType.APPLICATION_PROBLEM_XML_VALUE)) {
|
|
|
|
|
assertThat(this.servletResponse.getContentAsString()).isEqualTo(
|
|
|
|
|
"<problem xmlns=\"urn:ietf:rfc:7807\">" +
|
|
|
|
|
"<type>about:blank</type>" +
|
|
|
|
|
"<title>Bad Request</title>" +
|
|
|
|
|
"<status>400</status>" +
|
|
|
|
|
"<instance>/path</instance>" +
|
|
|
|
|
"</problem>");
|
|
|
|
|
XmlAssert.assertThat(this.servletResponse.getContentAsString()).and("""
|
|
|
|
|
<problem xmlns="urn:ietf:rfc:7807">
|
|
|
|
|
<type>about:blank</type>
|
|
|
|
|
<title>Bad Request</title>
|
|
|
|
|
<status>400</status>
|
|
|
|
|
<instance>/path</instance>
|
|
|
|
|
</problem>""")
|
|
|
|
|
.ignoreWhitespace()
|
|
|
|
|
.areIdentical();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
assertThat(this.servletResponse.getContentAsString()).isEqualTo(
|
|
|
|
|
"{\"type\":\"about:blank\"," +
|
|
|
|
|
"\"title\":\"Bad Request\"," +
|
|
|
|
|
"\"status\":400," +
|
|
|
|
|
"\"instance\":\"/path\"}");
|
|
|
|
|
JSONAssert.assertEquals("""
|
|
|
|
|
{
|
|
|
|
|
"type": "about:blank",
|
|
|
|
|
"title": "Bad Request",
|
|
|
|
|
"status": 400,
|
|
|
|
|
"instance": "/path"
|
|
|
|
|
}""", this.servletResponse.getContentAsString(), false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -461,24 +419,23 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test // SPR-13135
|
|
|
|
|
public void handleReturnValueWithInvalidReturnType() throws Exception {
|
|
|
|
|
void handleReturnValueWithInvalidReturnType() throws Exception {
|
|
|
|
|
Method method = getClass().getDeclaredMethod("handleAndReturnOutputStream");
|
|
|
|
|
MethodParameter returnType = new MethodParameter(method, -1);
|
|
|
|
|
assertThatIllegalArgumentException().isThrownBy(() -> {
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(new ArrayList<>());
|
|
|
|
|
processor.writeWithMessageConverters(new ByteArrayOutputStream(), returnType, this.request);
|
|
|
|
|
});
|
|
|
|
|
List<HttpMessageConverter<?>> converters = List.of(new StringHttpMessageConverter());
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
|
|
|
|
|
assertThatExceptionOfType(HttpMediaTypeNotAcceptableException.class).isThrownBy(() ->
|
|
|
|
|
processor.writeWithMessageConverters(new ByteArrayOutputStream(), returnType, this.request));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void addContentDispositionHeader() throws Exception {
|
|
|
|
|
void addContentDispositionHeader() throws Exception {
|
|
|
|
|
ContentNegotiationManagerFactoryBean factory = new ContentNegotiationManagerFactoryBean();
|
|
|
|
|
factory.addMediaType("pdf", new MediaType("application", "pdf"));
|
|
|
|
|
factory.afterPropertiesSet();
|
|
|
|
|
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(
|
|
|
|
|
Collections.singletonList(new StringHttpMessageConverter()),
|
|
|
|
|
factory.getObject());
|
|
|
|
|
List.of(new StringHttpMessageConverter()), factory.getObject());
|
|
|
|
|
|
|
|
|
|
assertContentDisposition(processor, false, "/hello.json", "safe extension");
|
|
|
|
|
assertContentDisposition(processor, false, "/hello.pdf", "registered extension");
|
|
|
|
@ -502,14 +459,13 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void addContentDispositionHeaderToErrorResponse() throws Exception {
|
|
|
|
|
void addContentDispositionHeaderToErrorResponse() throws Exception {
|
|
|
|
|
ContentNegotiationManagerFactoryBean factory = new ContentNegotiationManagerFactoryBean();
|
|
|
|
|
factory.addMediaType("pdf", new MediaType("application", "pdf"));
|
|
|
|
|
factory.afterPropertiesSet();
|
|
|
|
|
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(
|
|
|
|
|
Collections.singletonList(new StringHttpMessageConverter()),
|
|
|
|
|
factory.getObject());
|
|
|
|
|
List.of(new StringHttpMessageConverter()), factory.getObject());
|
|
|
|
|
|
|
|
|
|
this.servletRequest.setRequestURI("/hello.dataless");
|
|
|
|
|
this.servletResponse.setStatus(400);
|
|
|
|
@ -521,117 +477,105 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void supportsReturnTypeResponseBodyOnType() throws Exception {
|
|
|
|
|
void supportsReturnTypeResponseBodyOnType() throws Exception {
|
|
|
|
|
Method method = ResponseBodyController.class.getMethod("handle");
|
|
|
|
|
MethodParameter returnType = new MethodParameter(method, -1);
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
|
|
|
|
converters.add(new StringHttpMessageConverter());
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = List.of(new StringHttpMessageConverter());
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
|
|
|
|
|
|
|
|
|
|
assertThat(processor.supportsReturnType(returnType)).as("Failed to recognize type-level @ResponseBody").isTrue();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void supportsReturnTypeRestController() throws Exception {
|
|
|
|
|
void supportsReturnTypeRestController() throws Exception {
|
|
|
|
|
Method method = TestRestController.class.getMethod("handle");
|
|
|
|
|
MethodParameter returnType = new MethodParameter(method, -1);
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
|
|
|
|
converters.add(new StringHttpMessageConverter());
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = List.of(new StringHttpMessageConverter());
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
|
|
|
|
|
|
|
|
|
|
assertThat(processor.supportsReturnType(returnType)).as("Failed to recognize type-level @RestController").isTrue();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void jacksonJsonViewWithResponseBodyAndJsonMessageConverter() throws Exception {
|
|
|
|
|
void jacksonJsonViewWithResponseBodyAndJsonMessageConverter() throws Exception {
|
|
|
|
|
Method method = JacksonController.class.getMethod("handleResponseBody");
|
|
|
|
|
HandlerMethod handlerMethod = new HandlerMethod(new JacksonController(), method);
|
|
|
|
|
MethodParameter methodReturnType = handlerMethod.getReturnType();
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
|
|
|
|
converters.add(new MappingJackson2HttpMessageConverter());
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = List.of(new MappingJackson2HttpMessageConverter());
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(
|
|
|
|
|
converters, null, Collections.singletonList(new JsonViewResponseBodyAdvice()));
|
|
|
|
|
converters, null, List.of(new JsonViewResponseBodyAdvice()));
|
|
|
|
|
|
|
|
|
|
Object returnValue = new JacksonController().handleResponseBody();
|
|
|
|
|
processor.handleReturnValue(returnValue, methodReturnType, this.container, this.request);
|
|
|
|
|
|
|
|
|
|
String content = this.servletResponse.getContentAsString();
|
|
|
|
|
assertThat(content.contains("\"withView1\":\"with\"")).isFalse();
|
|
|
|
|
assertThat(content.contains("\"withView2\":\"with\"")).isTrue();
|
|
|
|
|
assertThat(content.contains("\"withoutView\":\"without\"")).isFalse();
|
|
|
|
|
assertThat(this.servletResponse.getContentAsString())
|
|
|
|
|
.doesNotContain("\"withView1\":\"with\"")
|
|
|
|
|
.contains("\"withView2\":\"with\"")
|
|
|
|
|
.doesNotContain("\"withoutView\":\"without\"");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void jacksonJsonViewWithResponseEntityAndJsonMessageConverter() throws Exception {
|
|
|
|
|
void jacksonJsonViewWithResponseEntityAndJsonMessageConverter() throws Exception {
|
|
|
|
|
Method method = JacksonController.class.getMethod("handleResponseEntity");
|
|
|
|
|
HandlerMethod handlerMethod = new HandlerMethod(new JacksonController(), method);
|
|
|
|
|
MethodParameter methodReturnType = handlerMethod.getReturnType();
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
|
|
|
|
converters.add(new MappingJackson2HttpMessageConverter());
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = List.of(new MappingJackson2HttpMessageConverter());
|
|
|
|
|
HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor(
|
|
|
|
|
converters, null, Collections.singletonList(new JsonViewResponseBodyAdvice()));
|
|
|
|
|
converters, null, List.of(new JsonViewResponseBodyAdvice()));
|
|
|
|
|
|
|
|
|
|
Object returnValue = new JacksonController().handleResponseEntity();
|
|
|
|
|
processor.handleReturnValue(returnValue, methodReturnType, this.container, this.request);
|
|
|
|
|
|
|
|
|
|
String content = this.servletResponse.getContentAsString();
|
|
|
|
|
assertThat(content.contains("\"withView1\":\"with\"")).isFalse();
|
|
|
|
|
assertThat(content.contains("\"withView2\":\"with\"")).isTrue();
|
|
|
|
|
assertThat(content.contains("\"withoutView\":\"without\"")).isFalse();
|
|
|
|
|
assertThat(this.servletResponse.getContentAsString())
|
|
|
|
|
.doesNotContain("\"withView1\":\"with\"")
|
|
|
|
|
.contains("\"withView2\":\"with\"")
|
|
|
|
|
.doesNotContain("\"withoutView\":\"without\"");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test // SPR-12149
|
|
|
|
|
public void jacksonJsonViewWithResponseBodyAndXmlMessageConverter() throws Exception {
|
|
|
|
|
void jacksonJsonViewWithResponseBodyAndXmlMessageConverter() throws Exception {
|
|
|
|
|
Method method = JacksonController.class.getMethod("handleResponseBody");
|
|
|
|
|
HandlerMethod handlerMethod = new HandlerMethod(new JacksonController(), method);
|
|
|
|
|
MethodParameter methodReturnType = handlerMethod.getReturnType();
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
|
|
|
|
converters.add(new MappingJackson2XmlHttpMessageConverter());
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = List.of(new MappingJackson2XmlHttpMessageConverter());
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(
|
|
|
|
|
converters, null, Collections.singletonList(new JsonViewResponseBodyAdvice()));
|
|
|
|
|
converters, null, List.of(new JsonViewResponseBodyAdvice()));
|
|
|
|
|
|
|
|
|
|
Object returnValue = new JacksonController().handleResponseBody();
|
|
|
|
|
processor.handleReturnValue(returnValue, methodReturnType, this.container, this.request);
|
|
|
|
|
|
|
|
|
|
String content = this.servletResponse.getContentAsString();
|
|
|
|
|
assertThat(content.contains("<withView1>with</withView1>")).isFalse();
|
|
|
|
|
assertThat(content.contains("<withView2>with</withView2>")).isTrue();
|
|
|
|
|
assertThat(content.contains("<withoutView>without</withoutView>")).isFalse();
|
|
|
|
|
assertThat(this.servletResponse.getContentAsString())
|
|
|
|
|
.doesNotContain("<withView1>with</withView1>")
|
|
|
|
|
.contains("<withView2>with</withView2>")
|
|
|
|
|
.doesNotContain("<withoutView>without</withoutView>");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test // SPR-12149
|
|
|
|
|
public void jacksonJsonViewWithResponseEntityAndXmlMessageConverter() throws Exception {
|
|
|
|
|
void jacksonJsonViewWithResponseEntityAndXmlMessageConverter() throws Exception {
|
|
|
|
|
Method method = JacksonController.class.getMethod("handleResponseEntity");
|
|
|
|
|
HandlerMethod handlerMethod = new HandlerMethod(new JacksonController(), method);
|
|
|
|
|
MethodParameter methodReturnType = handlerMethod.getReturnType();
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
|
|
|
|
converters.add(new MappingJackson2XmlHttpMessageConverter());
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = List.of(new MappingJackson2XmlHttpMessageConverter());
|
|
|
|
|
HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor(
|
|
|
|
|
converters, null, Collections.singletonList(new JsonViewResponseBodyAdvice()));
|
|
|
|
|
converters, null, List.of(new JsonViewResponseBodyAdvice()));
|
|
|
|
|
|
|
|
|
|
Object returnValue = new JacksonController().handleResponseEntity();
|
|
|
|
|
processor.handleReturnValue(returnValue, methodReturnType, this.container, this.request);
|
|
|
|
|
|
|
|
|
|
String content = this.servletResponse.getContentAsString();
|
|
|
|
|
assertThat(content.contains("<withView1>with</withView1>")).isFalse();
|
|
|
|
|
assertThat(content.contains("<withView2>with</withView2>")).isTrue();
|
|
|
|
|
assertThat(content.contains("<withoutView>without</withoutView>")).isFalse();
|
|
|
|
|
assertThat(this.servletResponse.getContentAsString())
|
|
|
|
|
.doesNotContain("<withView1>with</withView1>")
|
|
|
|
|
.contains("<withView2>with</withView2>")
|
|
|
|
|
.doesNotContain("<withoutView>without</withoutView>");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test // SPR-12501
|
|
|
|
|
public void resolveArgumentWithJacksonJsonView() throws Exception {
|
|
|
|
|
void resolveArgumentWithJacksonJsonView() throws Exception {
|
|
|
|
|
String content = "{\"withView1\" : \"with\", \"withView2\" : \"with\", \"withoutView\" : \"without\"}";
|
|
|
|
|
this.servletRequest.setContent(content.getBytes(StandardCharsets.UTF_8));
|
|
|
|
|
this.servletRequest.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
|
|
|
@ -640,11 +584,9 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
HandlerMethod handlerMethod = new HandlerMethod(new JacksonController(), method);
|
|
|
|
|
MethodParameter methodParameter = handlerMethod.getMethodParameters()[0];
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
|
|
|
|
converters.add(new MappingJackson2HttpMessageConverter());
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = List.of(new MappingJackson2HttpMessageConverter());
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(
|
|
|
|
|
converters, null, Collections.singletonList(new JsonViewRequestBodyAdvice()));
|
|
|
|
|
converters, null, List.of(new JsonViewRequestBodyAdvice()));
|
|
|
|
|
|
|
|
|
|
JacksonViewBean result = (JacksonViewBean)
|
|
|
|
|
processor.resolveArgument(methodParameter, this.container, this.request, this.factory);
|
|
|
|
@ -656,7 +598,7 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test // SPR-12501
|
|
|
|
|
public void resolveHttpEntityArgumentWithJacksonJsonView() throws Exception {
|
|
|
|
|
void resolveHttpEntityArgumentWithJacksonJsonView() throws Exception {
|
|
|
|
|
String content = "{\"withView1\" : \"with\", \"withView2\" : \"with\", \"withoutView\" : \"without\"}";
|
|
|
|
|
this.servletRequest.setContent(content.getBytes(StandardCharsets.UTF_8));
|
|
|
|
|
this.servletRequest.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
|
|
|
@ -665,11 +607,9 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
HandlerMethod handlerMethod = new HandlerMethod(new JacksonController(), method);
|
|
|
|
|
MethodParameter methodParameter = handlerMethod.getMethodParameters()[0];
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
|
|
|
|
converters.add(new MappingJackson2HttpMessageConverter());
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = List.of(new MappingJackson2HttpMessageConverter());
|
|
|
|
|
HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor(
|
|
|
|
|
converters, null, Collections.singletonList(new JsonViewRequestBodyAdvice()));
|
|
|
|
|
converters, null, List.of(new JsonViewRequestBodyAdvice()));
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
|
HttpEntity<JacksonViewBean> result = (HttpEntity<JacksonViewBean>)
|
|
|
|
@ -683,7 +623,7 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test // SPR-12501
|
|
|
|
|
public void resolveArgumentWithJacksonJsonViewAndXmlMessageConverter() throws Exception {
|
|
|
|
|
void resolveArgumentWithJacksonJsonViewAndXmlMessageConverter() throws Exception {
|
|
|
|
|
String content = "<root>" +
|
|
|
|
|
"<withView1>with</withView1>" +
|
|
|
|
|
"<withView2>with</withView2>" +
|
|
|
|
@ -695,11 +635,9 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
HandlerMethod handlerMethod = new HandlerMethod(new JacksonController(), method);
|
|
|
|
|
MethodParameter methodParameter = handlerMethod.getMethodParameters()[0];
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
|
|
|
|
converters.add(new MappingJackson2XmlHttpMessageConverter());
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = List.of(new MappingJackson2XmlHttpMessageConverter());
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(
|
|
|
|
|
converters, null, Collections.singletonList(new JsonViewRequestBodyAdvice()));
|
|
|
|
|
converters, null, List.of(new JsonViewRequestBodyAdvice()));
|
|
|
|
|
|
|
|
|
|
JacksonViewBean result = (JacksonViewBean)
|
|
|
|
|
processor.resolveArgument(methodParameter, this.container, this.request, this.factory);
|
|
|
|
@ -711,7 +649,7 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test // SPR-12501
|
|
|
|
|
public void resolveHttpEntityArgumentWithJacksonJsonViewAndXmlMessageConverter() throws Exception {
|
|
|
|
|
void resolveHttpEntityArgumentWithJacksonJsonViewAndXmlMessageConverter() throws Exception {
|
|
|
|
|
String content = "<root>" +
|
|
|
|
|
"<withView1>with</withView1>" +
|
|
|
|
|
"<withView2>with</withView2>" +
|
|
|
|
@ -723,11 +661,9 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
HandlerMethod handlerMethod = new HandlerMethod(new JacksonController(), method);
|
|
|
|
|
MethodParameter methodParameter = handlerMethod.getMethodParameters()[0];
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
|
|
|
|
converters.add(new MappingJackson2XmlHttpMessageConverter());
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = List.of(new MappingJackson2XmlHttpMessageConverter());
|
|
|
|
|
HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor(
|
|
|
|
|
converters, null, Collections.singletonList(new JsonViewRequestBodyAdvice()));
|
|
|
|
|
converters, null, List.of(new JsonViewRequestBodyAdvice()));
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
|
HttpEntity<JacksonViewBean> result = (HttpEntity<JacksonViewBean>)
|
|
|
|
@ -741,63 +677,60 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test // SPR-12811
|
|
|
|
|
public void jacksonTypeInfoList() throws Exception {
|
|
|
|
|
void jacksonTypeInfoList() throws Exception {
|
|
|
|
|
Method method = JacksonController.class.getMethod("handleTypeInfoList");
|
|
|
|
|
HandlerMethod handlerMethod = new HandlerMethod(new JacksonController(), method);
|
|
|
|
|
MethodParameter methodReturnType = handlerMethod.getReturnType();
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
|
|
|
|
converters.add(new MappingJackson2HttpMessageConverter());
|
|
|
|
|
List<HttpMessageConverter<?>> converters = List.of(new MappingJackson2HttpMessageConverter());
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
|
|
|
|
|
|
|
|
|
|
Object returnValue = new JacksonController().handleTypeInfoList();
|
|
|
|
|
processor.handleReturnValue(returnValue, methodReturnType, this.container, this.request);
|
|
|
|
|
|
|
|
|
|
String content = this.servletResponse.getContentAsString();
|
|
|
|
|
assertThat(content.contains("\"type\":\"foo\"")).isTrue();
|
|
|
|
|
assertThat(content.contains("\"type\":\"bar\"")).isTrue();
|
|
|
|
|
assertThat(this.servletResponse.getContentAsString())
|
|
|
|
|
.contains("\"type\":\"foo\"")
|
|
|
|
|
.contains("\"type\":\"bar\"");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test // SPR-13318
|
|
|
|
|
public void jacksonSubType() throws Exception {
|
|
|
|
|
void jacksonSubType() throws Exception {
|
|
|
|
|
Method method = JacksonController.class.getMethod("handleSubType");
|
|
|
|
|
HandlerMethod handlerMethod = new HandlerMethod(new JacksonController(), method);
|
|
|
|
|
MethodParameter methodReturnType = handlerMethod.getReturnType();
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
|
|
|
|
converters.add(new MappingJackson2HttpMessageConverter());
|
|
|
|
|
List<HttpMessageConverter<?>> converters = List.of(new MappingJackson2HttpMessageConverter());
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
|
|
|
|
|
|
|
|
|
|
Object returnValue = new JacksonController().handleSubType();
|
|
|
|
|
processor.handleReturnValue(returnValue, methodReturnType, this.container, this.request);
|
|
|
|
|
|
|
|
|
|
String content = this.servletResponse.getContentAsString();
|
|
|
|
|
assertThat(content.contains("\"id\":123")).isTrue();
|
|
|
|
|
assertThat(content.contains("\"name\":\"foo\"")).isTrue();
|
|
|
|
|
assertThat(this.servletResponse.getContentAsString())
|
|
|
|
|
.contains("\"id\":123")
|
|
|
|
|
.contains("\"name\":\"foo\"");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test // SPR-13318
|
|
|
|
|
public void jacksonSubTypeList() throws Exception {
|
|
|
|
|
void jacksonSubTypeList() throws Exception {
|
|
|
|
|
Method method = JacksonController.class.getMethod("handleSubTypeList");
|
|
|
|
|
HandlerMethod handlerMethod = new HandlerMethod(new JacksonController(), method);
|
|
|
|
|
MethodParameter methodReturnType = handlerMethod.getReturnType();
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
|
|
|
|
converters.add(new MappingJackson2HttpMessageConverter());
|
|
|
|
|
List<HttpMessageConverter<?>> converters = List.of(new MappingJackson2HttpMessageConverter());
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
|
|
|
|
|
|
|
|
|
|
Object returnValue = new JacksonController().handleSubTypeList();
|
|
|
|
|
processor.handleReturnValue(returnValue, methodReturnType, this.container, this.request);
|
|
|
|
|
|
|
|
|
|
String content = this.servletResponse.getContentAsString();
|
|
|
|
|
assertThat(content.contains("\"id\":123")).isTrue();
|
|
|
|
|
assertThat(content.contains("\"name\":\"foo\"")).isTrue();
|
|
|
|
|
assertThat(content.contains("\"id\":456")).isTrue();
|
|
|
|
|
assertThat(content.contains("\"name\":\"bar\"")).isTrue();
|
|
|
|
|
assertThat(this.servletResponse.getContentAsString())
|
|
|
|
|
.contains("\"id\":123")
|
|
|
|
|
.contains("\"name\":\"foo\"")
|
|
|
|
|
.contains("\"id\":456")
|
|
|
|
|
.contains("\"name\":\"bar\"");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test // SPR-14520
|
|
|
|
|
public void resolveArgumentTypeVariableWithGenericInterface() throws Exception {
|
|
|
|
|
void resolveArgumentTypeVariableWithGenericInterface() throws Exception {
|
|
|
|
|
this.servletRequest.setContent("\"foo\"".getBytes(StandardCharsets.UTF_8));
|
|
|
|
|
this.servletRequest.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
|
|
|
|
|
|
|
|
@ -805,9 +738,7 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
HandlerMethod handlerMethod = new HandlerMethod(new MyControllerImplementingInterface(), method);
|
|
|
|
|
MethodParameter methodParameter = handlerMethod.getMethodParameters()[0];
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
|
|
|
|
converters.add(new MappingJackson2HttpMessageConverter());
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = List.of(new MappingJackson2HttpMessageConverter());
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
|
|
|
|
|
|
|
|
|
|
assertThat(processor.supportsParameter(methodParameter)).isTrue();
|
|
|
|
@ -817,7 +748,7 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test // gh-24127
|
|
|
|
|
public void resolveArgumentTypeVariableWithGenericInterfaceAndSubclass() throws Exception {
|
|
|
|
|
void resolveArgumentTypeVariableWithGenericInterfaceAndSubclass() throws Exception {
|
|
|
|
|
this.servletRequest.setContent("\"foo\"".getBytes(StandardCharsets.UTF_8));
|
|
|
|
|
this.servletRequest.setContentType(MediaType.APPLICATION_JSON_VALUE);
|
|
|
|
|
|
|
|
|
@ -825,9 +756,7 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
HandlerMethod handlerMethod = new HandlerMethod(new SubControllerImplementingInterface(), method);
|
|
|
|
|
MethodParameter methodParameter = handlerMethod.getMethodParameters()[0];
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = new ArrayList<>();
|
|
|
|
|
converters.add(new MappingJackson2HttpMessageConverter());
|
|
|
|
|
|
|
|
|
|
List<HttpMessageConverter<?>> converters = List.of(new MappingJackson2HttpMessageConverter());
|
|
|
|
|
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
|
|
|
|
|
|
|
|
|
|
assertThat(processor.supportsParameter(methodParameter)).isTrue();
|
|
|
|
@ -854,9 +783,9 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
.isNull();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.servletRequest = new MockHttpServletRequest();
|
|
|
|
|
this.servletResponse = new MockHttpServletResponse();
|
|
|
|
|
this.request = new ServletWebRequest(servletRequest, servletResponse);
|
|
|
|
|
this.servletRequest.clearAttributes();
|
|
|
|
|
this.servletResponse.setCommitted(false);
|
|
|
|
|
this.servletResponse.reset();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -1087,10 +1016,7 @@ public class RequestResponseBodyMethodProcessorTests {
|
|
|
|
|
@ResponseBody
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
|
public List<T> handleTypeInfoList() {
|
|
|
|
|
List<T> list = new ArrayList<>();
|
|
|
|
|
list.add((T) new Foo("foo"));
|
|
|
|
|
list.add((T) new Bar("bar"));
|
|
|
|
|
return list;
|
|
|
|
|
return List.of((T) new Foo("foo"), (T) new Bar("bar"));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|