@SuppressWarnings("unchecked") private <T> void sendInternal(T data, @Nullable MediaType mediaType) throws IOException { for (HttpMessageConverter<?> converter : ResponseBodyEmitterReturnValueHandler.this.messageConverters) { if (converter.canWrite(data.getClass(), mediaType)) { ((HttpMessageConverter<T>) converter).write(data, mediaType, this.outputMessage); this.outputMessage.flush(); return; } } throw new IllegalArgumentException("No suitable converter for " + data.getClass()); }
@Test public void canWrite() { MediaType mediaType = new MediaType("foo", "bar"); HttpMessageConverter<MyType> converter = new MyHttpMessageConverter<>(mediaType); assertTrue(converter.canWrite(MyType.class, mediaType)); assertTrue(converter.canWrite(MyType.class, new MediaType("foo", "*"))); assertTrue(converter.canWrite(MyType.class, MediaType.ALL)); }
@Test public void canWriteWithWildcardInSupportedSubtype() { MediaType mediaType = new MediaType("foo"); HttpMessageConverter<MyType> converter = new MyHttpMessageConverter<>(mediaType); assertTrue(converter.canWrite(MyType.class, new MediaType("foo", "bar"))); assertTrue(converter.canWrite(MyType.class, new MediaType("foo", "*"))); assertTrue(converter.canWrite(MyType.class, MediaType.ALL)); }
private void initStringMessageConversion(MediaType accepted) { given(stringHttpMessageConverter.canWrite(String.class, null)).willReturn(true); given(stringHttpMessageConverter.getSupportedMediaTypes()).willReturn(Collections.singletonList(TEXT_PLAIN)); given(stringHttpMessageConverter.canWrite(String.class, accepted)).willReturn(true); }
@Test public void shouldFailHandlingWhenConverterCannotWrite() throws Exception { String body = "Foo"; ResponseEntity<String> returnValue = new ResponseEntity<>(body, HttpStatus.OK); MediaType accepted = TEXT_PLAIN; servletRequest.addHeader("Accept", accepted.toString()); given(stringHttpMessageConverter.canWrite(String.class, null)).willReturn(true); given(stringHttpMessageConverter.getSupportedMediaTypes()) .willReturn(Collections.singletonList(TEXT_PLAIN)); given(stringHttpMessageConverter.canWrite(String.class, accepted)).willReturn(false); this.thrown.expect(HttpMediaTypeNotAcceptableException.class); processor.handleReturnValue(returnValue, returnTypeResponseEntityProduces, mavContainer, webRequest); }
@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 shouldFailHandlingWhenContentTypeNotSupported() throws Exception { String body = "Foo"; ResponseEntity<String> returnValue = new ResponseEntity<>(body, HttpStatus.OK); MediaType accepted = MediaType.APPLICATION_ATOM_XML; servletRequest.addHeader("Accept", accepted.toString()); given(stringHttpMessageConverter.canWrite(String.class, null)).willReturn(true); given(stringHttpMessageConverter.getSupportedMediaTypes()) .willReturn(Collections.singletonList(TEXT_PLAIN)); this.thrown.expect(HttpMediaTypeNotAcceptableException.class); processor.handleReturnValue(returnValue, returnTypeResponseEntity, mavContainer, webRequest); }
@Test public void shouldHandleResource() throws Exception { ResponseEntity<Resource> returnValue = ResponseEntity .ok(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, APPLICATION_OCTET_STREAM)).willReturn(true); processor.handleReturnValue(returnValue, returnTypeResponseEntityResource, mavContainer, webRequest); then(resourceMessageConverter).should(times(1)).write( any(ByteArrayResource.class), eq(APPLICATION_OCTET_STREAM), any(HttpOutputMessage.class)); assertEquals(200, servletResponse.getStatus()); }
private void mockHttpMessageConverter(MediaType mediaType, Class type) { given(converter.canRead(type, null)).willReturn(true); given(converter.canRead(type, mediaType)).willReturn(true); given(converter.getSupportedMediaTypes()) .willReturn(Collections.singletonList(mediaType)); given(converter.canRead(type, mediaType)).willReturn(true); given(converter.canWrite(type, null)).willReturn(true); given(converter.canWrite(type, mediaType)).willReturn(true); }
@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 shouldHandleReturnValueWithProducibleMediaType() throws Exception { String body = "Foo"; ResponseEntity<String> returnValue = new ResponseEntity<>(body, HttpStatus.OK); servletRequest.addHeader("Accept", "text/*"); servletRequest.setAttribute(PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE, Collections.singleton(MediaType.TEXT_HTML)); given(stringHttpMessageConverter.canWrite(String.class, MediaType.TEXT_HTML)).willReturn(true); processor.handleReturnValue(returnValue, returnTypeResponseEntityProduces, mavContainer, webRequest); assertTrue(mavContainer.isRequestHandled()); verify(stringHttpMessageConverter).write(eq(body), eq(MediaType.TEXT_HTML), isA(HttpOutputMessage.class)); }
@Test public void shouldHandleResourceByteRange() throws Exception { ResponseEntity<Resource> returnValue = ResponseEntity .ok(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(APPLICATION_OCTET_STREAM))).willReturn(true); processor.handleReturnValue(returnValue, returnTypeResponseEntityResource, mavContainer, webRequest); then(resourceRegionMessageConverter).should(times(1)).write( anyCollection(), eq(APPLICATION_OCTET_STREAM), argThat(outputMessage -> "bytes".equals(outputMessage.getHeaders().getFirst(HttpHeaders.ACCEPT_RANGES)))); assertEquals(206, servletResponse.getStatus()); }
@Test public void handleReturnTypeResourceIllegalByteRange() throws Exception { ResponseEntity<Resource> returnValue = ResponseEntity .ok(new ByteArrayResource("Content".getBytes(StandardCharsets.UTF_8))); servletRequest.addHeader("Range", "illegal"); given(resourceRegionMessageConverter.canWrite(any(), eq(null))).willReturn(true); given(resourceRegionMessageConverter.canWrite(any(), eq(APPLICATION_OCTET_STREAM))).willReturn(true); processor.handleReturnValue(returnValue, returnTypeResponseEntityResource, mavContainer, webRequest); then(resourceRegionMessageConverter).should(never()).write( anyCollection(), eq(APPLICATION_OCTET_STREAM), any(HttpOutputMessage.class)); assertEquals(416, 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-16921 public void disableRangeSupportIfContentRangePresent() throws Exception { ResponseEntity<Resource> returnValue = ResponseEntity .status(HttpStatus.PARTIAL_CONTENT) .header(HttpHeaders.RANGE, "bytes=0-5") .body(new ByteArrayResource("Content".getBytes(StandardCharsets.UTF_8))); given(resourceRegionMessageConverter.canWrite(any(), eq(null))).willReturn(true); given(resourceRegionMessageConverter.canWrite(any(), eq(APPLICATION_OCTET_STREAM))).willReturn(true); processor.handleReturnValue(returnValue, returnTypeResponseEntityResource, mavContainer, webRequest); then(resourceRegionMessageConverter).should(never()).write(anyCollection(), any(), any()); assertEquals(206, servletResponse.getStatus()); }
@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 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 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()); }
@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)); }