@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()); }
@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()); }
private void assertResponseBody(String body) throws IOException { ArgumentCaptor<HttpOutputMessage> outputMessage = ArgumentCaptor.forClass(HttpOutputMessage.class); verify(stringHttpMessageConverter).write(eq(body), eq(TEXT_PLAIN), outputMessage.capture()); }
@Test public void shouldHandleResponseHeaderAndBody() throws Exception { HttpHeaders responseHeaders = new HttpHeaders(); responseHeaders.set("header", "headerValue"); ResponseEntity<String> returnValue = new ResponseEntity<>("body", responseHeaders, HttpStatus.ACCEPTED); initStringMessageConversion(TEXT_PLAIN); processor.handleReturnValue(returnValue, returnTypeResponseEntity, mavContainer, webRequest); ArgumentCaptor<HttpOutputMessage> outputMessage = ArgumentCaptor.forClass(HttpOutputMessage.class); verify(stringHttpMessageConverter).write(eq("body"), eq(TEXT_PLAIN), outputMessage.capture()); assertTrue(mavContainer.isRequestHandled()); assertEquals("headerValue", outputMessage.getValue().getHeaders().get("header").get(0)); }
@SuppressWarnings("unchecked") private void writePart(String name, HttpEntity<?> partEntity, OutputStream os) throws IOException { Object partBody = partEntity.getBody(); if (partBody == null) { throw new IllegalStateException("Empty body for part '" + name + "': " + partEntity); } Class<?> partType = partBody.getClass(); HttpHeaders partHeaders = partEntity.getHeaders(); MediaType partContentType = partHeaders.getContentType(); for (HttpMessageConverter<?> messageConverter : this.partConverters) { if (messageConverter.canWrite(partType, partContentType)) { Charset charset = isFilenameCharsetSet() ? StandardCharsets.US_ASCII : this.charset; HttpOutputMessage multipartMessage = new MultipartHttpOutputMessage(os, charset); multipartMessage.getHeaders().setContentDispositionFormData(name, getFilename(partBody)); if (!partHeaders.isEmpty()) { multipartMessage.getHeaders().putAll(partHeaders); } ((HttpMessageConverter<Object>) messageConverter).write(partBody, partContentType, multipartMessage); return; } } throw new HttpMessageNotWritableException("Could not write request: no suitable HttpMessageConverter " + "found for request type [" + partType.getName() + "]"); }
private void testVaryHeader(String[] entityValues, String[] existingValues, String[] expected) throws Exception { ResponseEntity<String> returnValue = ResponseEntity.ok().varyBy(entityValues).body("Foo"); for (String value : existingValues) { servletResponse.addHeader("Vary", value); } initStringMessageConversion(TEXT_PLAIN); processor.handleReturnValue(returnValue, returnTypeResponseEntity, mavContainer, webRequest); assertTrue(mavContainer.isRequestHandled()); assertEquals(Arrays.asList(expected), servletResponse.getHeaders("Vary")); verify(stringHttpMessageConverter).write(eq("Foo"), eq(TEXT_PLAIN), isA(HttpOutputMessage.class)); }
@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 shouldHandleReturnValue() throws Exception { String body = "Foo"; ResponseEntity<String> returnValue = new ResponseEntity<>(body, HttpStatus.OK); MediaType accepted = TEXT_PLAIN; servletRequest.addHeader("Accept", accepted.toString()); initStringMessageConversion(accepted); processor.handleReturnValue(returnValue, returnTypeResponseEntity, mavContainer, webRequest); assertTrue(mavContainer.isRequestHandled()); verify(stringHttpMessageConverter).write(eq(body), eq(accepted), isA(HttpOutputMessage.class)); }
@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()); }
@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 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 //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-16754 public void disableRangeSupportForStreamingResponses() throws Exception { InputStream is = new ByteArrayInputStream("Content".getBytes(StandardCharsets.UTF_8)); InputStreamResource resource = new InputStreamResource(is, "test"); ResponseEntity<Resource> returnValue = ResponseEntity.ok(resource); servletRequest.addHeader("Range", "bytes=0-5"); given(resourceMessageConverter.canWrite(any(), eq(null))).willReturn(true); given(resourceMessageConverter.canWrite(any(), eq(APPLICATION_OCTET_STREAM))).willReturn(true); processor.handleReturnValue(returnValue, returnTypeResponseEntityResource, mavContainer, webRequest); then(resourceMessageConverter).should(times(1)).write( any(InputStreamResource.class), eq(APPLICATION_OCTET_STREAM), any(HttpOutputMessage.class)); assertEquals(200, servletResponse.getStatus()); assertThat(servletResponse.getHeader(HttpHeaders.ACCEPT_RANGES), Matchers.isEmptyOrNullString()); }
@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 @SuppressWarnings("unchecked") public void shouldHandleReturnValueWithResponseBodyAdvice() throws Exception { servletRequest.addHeader("Accept", "text/*"); servletRequest.setAttribute(PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE, Collections.singleton(MediaType.TEXT_HTML)); ResponseEntity<String> returnValue = new ResponseEntity<>(HttpStatus.OK); ResponseBodyAdvice<String> advice = mock(ResponseBodyAdvice.class); given(advice.supports(any(), any())).willReturn(true); given(advice.beforeBodyWrite(any(), any(), any(), any(), any(), any())).willReturn("Foo"); HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor( Collections.singletonList(stringHttpMessageConverter), null, Collections.singletonList(advice)); reset(stringHttpMessageConverter); given(stringHttpMessageConverter.canWrite(String.class, MediaType.TEXT_HTML)).willReturn(true); processor.handleReturnValue(returnValue, returnTypeResponseEntity, mavContainer, webRequest); assertTrue(mavContainer.isRequestHandled()); verify(stringHttpMessageConverter).write(eq("Foo"), eq(MediaType.TEXT_HTML), isA(HttpOutputMessage.class)); }
@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()); }