@Test // SPR-13423 public void handleReturnValueCharSequence() throws Exception { List<HttpMessageConverter<?>>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, container, request); assertEquals("text/plain;charset=ISO-8859-1", servletResponse.getHeader("Content-Type")); assertEquals("Foo", servletResponse.getContentAsString()); }
@Test // SPR-13318 public 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()); RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters); Object returnValue = new JacksonController().handleSubType(); processor.handleReturnValue(returnValue, methodReturnType, this.container, this.request); String content = this.servletResponse.getContentAsString(); assertTrue(content.contains("\"id\":123")); assertTrue(content.contains("\"name\":\"foo\"")); }
@Test public void handleReturnValueString() throws Exception { List<HttpMessageConverter<?>>converters = new ArrayList<>(); converters.add(new ByteArrayHttpMessageConverter()); converters.add(new StringHttpMessageConverter()); RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters); processor.handleReturnValue("Foo", returnTypeString, container, request); assertEquals("text/plain;charset=ISO-8859-1", servletResponse.getHeader("Content-Type")); assertEquals("Foo", servletResponse.getContentAsString()); }
@Test // SPR-12811 public 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()); RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters); Object returnValue = new JacksonController().handleTypeInfoList(); processor.handleReturnValue(returnValue, methodReturnType, this.container, this.request); String content = this.servletResponse.getContentAsString(); assertTrue(content.contains("\"type\":\"foo\"")); assertTrue(content.contains("\"type\":\"bar\"")); }
@Test // SPR-13631 public void defaultCharset() throws Exception { Method method = JacksonController.class.getMethod("defaultCharset"); HandlerMethod handlerMethod = new HandlerMethod(new JacksonController(), method); MethodParameter methodReturnType = handlerMethod.getReturnType(); List<HttpMessageConverter<?>> converters = new ArrayList<>(); converters.add(new MappingJackson2HttpMessageConverter()); RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters); Object returnValue = new JacksonController().defaultCharset(); processor.handleReturnValue(returnValue, methodReturnType, this.container, this.request); assertEquals("UTF-8", this.servletResponse.getCharacterEncoding()); }
@Test // SPR-13318 public 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()); RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters); Object returnValue = new JacksonController().handleSubTypeList(); processor.handleReturnValue(returnValue, methodReturnType, this.container, this.request); String content = this.servletResponse.getContentAsString(); assertTrue(content.contains("\"id\":123")); assertTrue(content.contains("\"name\":\"foo\"")); assertTrue(content.contains("\"id\":456")); assertTrue(content.contains("\"name\":\"bar\"")); }
@Test public 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()); RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor( converters, null, Collections.singletonList(new JsonViewResponseBodyAdvice())); Object returnValue = new JacksonController().handleResponseBody(); processor.handleReturnValue(returnValue, methodReturnType, this.container, this.request); String content = this.servletResponse.getContentAsString(); assertFalse(content.contains("\"withView1\":\"with\"")); assertTrue(content.contains("\"withView2\":\"with\"")); assertFalse(content.contains("\"withoutView\":\"without\"")); }
@Test // SPR-12149 public 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()); RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor( converters, null, Collections.singletonList(new JsonViewResponseBodyAdvice())); Object returnValue = new JacksonController().handleResponseBody(); processor.handleReturnValue(returnValue, methodReturnType, this.container, this.request); String content = this.servletResponse.getContentAsString(); assertFalse(content.contains("<withView1>with</withView1>")); assertTrue(content.contains("<withView2>with</withView2>")); assertFalse(content.contains("<withoutView>without</withoutView>")); }
private void assertContentDisposition(RequestResponseBodyMethodProcessor processor, boolean expectContentDisposition, String requestURI, String comment) throws Exception { this.servletRequest.setRequestURI(requestURI); processor.handleReturnValue("body", this.returnTypeString, this.container, this.request); String header = servletResponse.getHeader("Content-Disposition"); if (expectContentDisposition) { assertEquals("Expected 'Content-Disposition' header. Use case: '" + comment + "'", "inline;filename=f.txt", header); } else { assertNull("Did not expect 'Content-Disposition' header. Use case: '" + comment + "'", header); } this.servletRequest = new MockHttpServletRequest(); this.servletResponse = new MockHttpServletResponse(); this.request = new ServletWebRequest(servletRequest, servletResponse); }
@Test(expected = HttpMediaTypeNotAcceptableException.class) public void handleReturnValueNotAcceptable() throws Exception { MediaType accepted = MediaType.APPLICATION_ATOM_XML; servletRequest.addHeader("Accept", accepted.toString()); given(stringMessageConverter.canWrite(String.class, null)).willReturn(true); given(stringMessageConverter.getSupportedMediaTypes()).willReturn(Arrays.asList(MediaType.TEXT_PLAIN)); given(stringMessageConverter.canWrite(String.class, accepted)).willReturn(false); processor.handleReturnValue("Foo", returnTypeString, mavContainer, webRequest); }
@Test(expected = HttpMediaTypeNotAcceptableException.class) public void handleReturnValueNotAcceptableProduces() throws Exception { MediaType accepted = MediaType.TEXT_PLAIN; servletRequest.addHeader("Accept", accepted.toString()); given(stringMessageConverter.canWrite(String.class, null)).willReturn(true); given(stringMessageConverter.getSupportedMediaTypes()).willReturn(Collections.singletonList(MediaType.TEXT_PLAIN)); given(stringMessageConverter.canWrite(String.class, accepted)).willReturn(false); processor.handleReturnValue("Foo", returnTypeStringProduces, mavContainer, webRequest); }
@Test public void handleReturnValueProduces() throws Exception { String body = "Foo"; servletRequest.addHeader("Accept", "text/*"); servletRequest.setAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE, Collections.singleton(MediaType.TEXT_HTML)); given(stringMessageConverter.canWrite(String.class, MediaType.TEXT_HTML)).willReturn(true); processor.handleReturnValue(body, returnTypeStringProduces, mavContainer, webRequest); assertTrue(mavContainer.isRequestHandled()); verify(stringMessageConverter).write(eq(body), eq(MediaType.TEXT_HTML), isA(HttpOutputMessage.class)); }
@Test public void handleReturnTypeResource() throws Exception { Resource returnValue = new ByteArrayResource("Content".getBytes(StandardCharsets.UTF_8)); given(resourceMessageConverter.canWrite(ByteArrayResource.class, null)).willReturn(true); given(resourceMessageConverter.getSupportedMediaTypes()).willReturn(Collections.singletonList(MediaType.ALL)); given(resourceMessageConverter.canWrite(ByteArrayResource.class, MediaType.APPLICATION_OCTET_STREAM)) .willReturn(true); processor.handleReturnValue(returnValue, returnTypeResource, mavContainer, webRequest); then(resourceMessageConverter).should(times(1)).write(any(ByteArrayResource.class), eq(MediaType.APPLICATION_OCTET_STREAM), any(HttpOutputMessage.class)); assertEquals(200, servletResponse.getStatus()); }
@Test public void handleReturnTypeResourceByteRange() throws Exception { Resource returnValue = new ByteArrayResource("Content".getBytes(StandardCharsets.UTF_8)); servletRequest.addHeader("Range", "bytes=0-5"); given(resourceRegionMessageConverter.canWrite(any(), eq(null))).willReturn(true); given(resourceRegionMessageConverter.canWrite(any(), eq(MediaType.APPLICATION_OCTET_STREAM))).willReturn(true); processor.handleReturnValue(returnValue, returnTypeResource, mavContainer, webRequest); then(resourceRegionMessageConverter).should(times(1)).write( anyCollection(), eq(MediaType.APPLICATION_OCTET_STREAM), argThat(outputMessage -> "bytes".equals(outputMessage.getHeaders().getFirst(HttpHeaders.ACCEPT_RANGES)))); assertEquals(206, servletResponse.getStatus()); }
@Test public void handleReturnValue() throws Exception { MediaType accepted = MediaType.TEXT_PLAIN; servletRequest.addHeader("Accept", accepted.toString()); String body = "Foo"; given(stringMessageConverter.canWrite(String.class, null)).willReturn(true); given(stringMessageConverter.getSupportedMediaTypes()).willReturn(Collections.singletonList(MediaType.TEXT_PLAIN)); given(stringMessageConverter.canWrite(String.class, accepted)).willReturn(true); processor.handleReturnValue(body, returnTypeString, mavContainer, webRequest); assertTrue("The requestHandled flag wasn't set", mavContainer.isRequestHandled()); verify(stringMessageConverter).write(eq(body), eq(accepted), isA(HttpOutputMessage.class)); }
@Test // SPR-9841 public void handleReturnValueMediaTypeSuffix() throws Exception { String body = "Foo"; MediaType accepted = MediaType.APPLICATION_XHTML_XML; List<MediaType> supported = Collections.singletonList(MediaType.valueOf("application/*+xml")); servletRequest.addHeader("Accept", accepted); given(stringMessageConverter.canWrite(String.class, null)).willReturn(true); given(stringMessageConverter.getSupportedMediaTypes()).willReturn(supported); given(stringMessageConverter.canWrite(String.class, accepted)).willReturn(true); processor.handleReturnValue(body, returnTypeStringProduces, mavContainer, webRequest); assertTrue(mavContainer.isRequestHandled()); verify(stringMessageConverter).write(eq(body), eq(accepted), isA(HttpOutputMessage.class)); }
@Test public void handleReturnTypeResourceIllegalByteRange() throws Exception { Resource returnValue = new ByteArrayResource("Content".getBytes(StandardCharsets.UTF_8)); servletRequest.addHeader("Range", "illegal"); given(resourceRegionMessageConverter.canWrite(any(), eq(null))).willReturn(true); given(resourceRegionMessageConverter.canWrite(any(), eq(MediaType.APPLICATION_OCTET_STREAM))).willReturn(true); processor.handleReturnValue(returnValue, returnTypeResource, mavContainer, webRequest); then(resourceRegionMessageConverter).should(never()).write( anyCollection(), eq(MediaType.APPLICATION_OCTET_STREAM), any(HttpOutputMessage.class)); assertEquals(416, servletResponse.getStatus()); }
@Override public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws IOException, HttpMediaTypeNotAcceptableException { try { ThreadLocalHolder.store("__GENSON$return_param", returnType); super.handleReturnValue(returnValue, returnType, mavContainer, webRequest); } finally { ThreadLocalHolder.remove("__GENSON$return_param", MethodParameter.class); } } }
@Override public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws IOException, HttpMediaTypeNotAcceptableException { try { ThreadLocalHolder.store("__GENSON$return_param", returnType); super.handleReturnValue(returnValue, returnType, mavContainer, webRequest); } finally { ThreadLocalHolder.remove("__GENSON$return_param", MethodParameter.class); } } }