diff --git a/spring-web/src/main/java/org/springframework/http/converter/ResourceRegionHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/ResourceRegionHttpMessageConverter.java index 35e98ddd08c..6a23f98e464 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/ResourceRegionHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/ResourceRegionHttpMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -29,7 +29,9 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.HttpInputMessage; import org.springframework.http.HttpOutputMessage; import org.springframework.http.MediaType; +import org.springframework.http.MediaTypeFactory; import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; import org.springframework.util.MimeTypeUtils; import org.springframework.util.StreamUtils; @@ -42,6 +44,9 @@ import org.springframework.util.StreamUtils; */ public class ResourceRegionHttpMessageConverter extends AbstractGenericHttpMessageConverter { + private static final boolean jafPresent = ClassUtils.isPresent( + "javax.activation.FileTypeMap", ResourceHttpMessageConverter.class.getClassLoader()); + public ResourceRegionHttpMessageConverter() { super(MediaType.ALL); } @@ -72,6 +77,23 @@ public class ResourceRegionHttpMessageConverter extends AbstractGenericHttpMessa return null; } + @Override + @SuppressWarnings("unchecked") + protected MediaType getDefaultContentType(Object object) { + if (jafPresent) { + if(object instanceof ResourceRegion) { + return MediaTypeFactory.getMediaType(((ResourceRegion) object).getResource()); + } + else { + Collection regions = (Collection) object; + if(regions.size() > 0) { + return MediaTypeFactory.getMediaType(regions.iterator().next().getResource()); + } + } + } + return MediaType.APPLICATION_OCTET_STREAM; + } + @Override public boolean canWrite(Class clazz, MediaType mediaType) { return canWrite(clazz, null, mediaType); diff --git a/spring-web/src/test/java/org/springframework/http/converter/ResourceRegionHttpMessageConverterTests.java b/spring-web/src/test/java/org/springframework/http/converter/ResourceRegionHttpMessageConverterTests.java index b75d596ea45..e05595569bd 100644 --- a/spring-web/src/test/java/org/springframework/http/converter/ResourceRegionHttpMessageConverterTests.java +++ b/spring-web/src/test/java/org/springframework/http/converter/ResourceRegionHttpMessageConverterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2017 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. @@ -16,13 +16,17 @@ package org.springframework.http.converter; +import java.io.ByteArrayInputStream; import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import org.hamcrest.Matchers; import org.junit.Test; +import org.mockito.BDDMockito; +import org.mockito.Mockito; import org.springframework.core.ParameterizedTypeReference; import org.springframework.core.io.ClassPathResource; @@ -34,8 +38,10 @@ import org.springframework.http.MediaType; import org.springframework.http.MockHttpOutputMessage; import org.springframework.util.StringUtils; -import static org.hamcrest.Matchers.*; -import static org.junit.Assert.*; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; /** * Test cases for {@link ResourceRegionHttpMessageConverter} class. @@ -139,4 +145,21 @@ public class ResourceRegionHttpMessageConverterTests { assertThat(ranges[15], is("resource content.")); } + @Test // SPR-15041 + public void applicationOctetStreamDefaultContentType() throws Exception { + MockHttpOutputMessage outputMessage = new MockHttpOutputMessage(); + ClassPathResource body = Mockito.mock(ClassPathResource.class); + BDDMockito.given(body.getFilename()).willReturn("spring.dat"); + BDDMockito.given(body.contentLength()).willReturn(12L); + BDDMockito.given(body.getInputStream()).willReturn(new ByteArrayInputStream("Spring Framework".getBytes())); + HttpRange range = HttpRange.createByteRange(0, 5); + ResourceRegion resourceRegion = range.toResourceRegion(body); + + converter.write(Collections.singletonList(resourceRegion), null, outputMessage); + + assertThat(outputMessage.getHeaders().getContentType(), is(MediaType.APPLICATION_OCTET_STREAM)); + assertThat(outputMessage.getHeaders().getFirst(HttpHeaders.CONTENT_RANGE), is("bytes 0-5/12")); + assertThat(outputMessage.getBodyAsString(StandardCharsets.UTF_8), is("Spring")); + } + } \ No newline at end of file