diff --git a/spring-context/src/test/java/org/springframework/scripting/support/ResourceScriptSourceTests.java b/spring-context/src/test/java/org/springframework/scripting/support/ResourceScriptSourceTests.java index df7ea2a03e6..41a93aedcd9 100644 --- a/spring-context/src/test/java/org/springframework/scripting/support/ResourceScriptSourceTests.java +++ b/spring-context/src/test/java/org/springframework/scripting/support/ResourceScriptSourceTests.java @@ -16,13 +16,13 @@ package org.springframework.scripting.support; -import java.io.ByteArrayInputStream; import java.io.IOException; import org.junit.Test; import org.springframework.core.io.ByteArrayResource; import org.springframework.core.io.Resource; +import org.springframework.util.StreamUtils; import static org.junit.Assert.*; import static org.mockito.BDDMockito.*; @@ -59,7 +59,7 @@ public class ResourceScriptSourceTests { // does not support File-based reading; delegates to InputStream-style reading... //resource.getFile(); //mock.setThrowable(new FileNotFoundException()); - given(resource.getInputStream()).willReturn(new ByteArrayInputStream(new byte[0])); + given(resource.getInputStream()).willReturn(StreamUtils.emptyInput()); ResourceScriptSource scriptSource = new ResourceScriptSource(resource); assertTrue("ResourceScriptSource must start off in the 'isModified' state (it obviously isn't).", scriptSource.isModified()); diff --git a/spring-core/src/main/java/org/springframework/util/StreamUtils.java b/spring-core/src/main/java/org/springframework/util/StreamUtils.java index b08cc83230c..1bc2170c47a 100644 --- a/spring-core/src/main/java/org/springframework/util/StreamUtils.java +++ b/spring-core/src/main/java/org/springframework/util/StreamUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2015 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,6 +16,7 @@ package org.springframework.util; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.FilterInputStream; import java.io.FilterOutputStream; @@ -43,6 +44,8 @@ public abstract class StreamUtils { public static final int BUFFER_SIZE = 4096; + private static final byte[] EMPTY_CONTENT = new byte[0]; + /** * Copy the contents of the given InputStream into a new byte array. @@ -129,7 +132,16 @@ public abstract class StreamUtils { } /** - * Returns a variant of the given {@link InputStream} where calling + * Return an efficient empty {@link InputStream}. + * @return a {@link ByteArrayInputStream} based on an empty byte array + * @since 4.2.2 + */ + public static InputStream emptyInput() { + return new ByteArrayInputStream(EMPTY_CONTENT); + } + + /** + * Return a variant of the given {@link InputStream} where calling * {@link InputStream#close() close()} has no effect. * @param in the InputStream to decorate * @return a version of the InputStream that ignores calls to close @@ -140,7 +152,7 @@ public abstract class StreamUtils { } /** - * Returns a variant of the given {@link OutputStream} where calling + * Return a variant of the given {@link OutputStream} where calling * {@link OutputStream#close() close()} has no effect. * @param out the OutputStream to decorate * @return a version of the OutputStream that ignores calls to close diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletRequest.java b/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletRequest.java index 0e08f14ec43..01840d66ce1 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletRequest.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletRequest.java @@ -39,7 +39,6 @@ import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.TimeZone; - import javax.servlet.AsyncContext; import javax.servlet.DispatcherType; import javax.servlet.RequestDispatcher; @@ -59,6 +58,7 @@ import org.springframework.util.Assert; import org.springframework.util.LinkedCaseInsensitiveMap; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; +import org.springframework.util.StreamUtils; import org.springframework.util.StringUtils; /** @@ -122,7 +122,7 @@ public class MockHttpServletRequest implements HttpServletRequest { private static final String CHARSET_PREFIX = "charset="; private static final ServletInputStream EMPTY_SERVLET_INPUT_STREAM = - new DelegatingServletInputStream(new ByteArrayInputStream(new byte[0])); + new DelegatingServletInputStream(StreamUtils.emptyInput()); /** * Date formats as specified in the HTTP RFC diff --git a/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.java b/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.java index 67284e78cfa..f723935b043 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.java +++ b/spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.java @@ -16,7 +16,6 @@ package org.springframework.http.converter.json; -import java.io.ByteArrayInputStream; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Arrays; @@ -54,6 +53,7 @@ import org.springframework.beans.FatalBeanException; import org.springframework.context.ApplicationContext; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; +import org.springframework.util.StreamUtils; import org.springframework.util.StringUtils; /** @@ -761,7 +761,7 @@ public class Jackson2ObjectMapperBuilder { private static final XMLResolver NO_OP_XML_RESOLVER = new XMLResolver() { @Override public Object resolveEntity(String publicID, String systemID, String base, String ns) { - return new ByteArrayInputStream(new byte[0]); + return StreamUtils.emptyInput(); } }; } diff --git a/spring-web/src/main/java/org/springframework/http/converter/xml/Jaxb2CollectionHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/xml/Jaxb2CollectionHttpMessageConverter.java index cbea3638744..91bc8f27154 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/xml/Jaxb2CollectionHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/xml/Jaxb2CollectionHttpMessageConverter.java @@ -16,7 +16,6 @@ package org.springframework.http.converter.xml; -import java.io.ByteArrayInputStream; import java.io.IOException; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; @@ -46,6 +45,7 @@ import org.springframework.http.converter.GenericHttpMessageConverter; import org.springframework.http.converter.HttpMessageConversionException; import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.http.converter.HttpMessageNotWritableException; +import org.springframework.util.StreamUtils; /** * An {@code HttpMessageConverter} that can read XML collections using JAXB2. @@ -256,7 +256,7 @@ public class Jaxb2CollectionHttpMessageConverter private static final XMLResolver NO_OP_XML_RESOLVER = new XMLResolver() { @Override public Object resolveEntity(String publicID, String systemID, String base, String ns) { - return new ByteArrayInputStream(new byte[0]); + return StreamUtils.emptyInput(); } }; diff --git a/spring-web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java index 3b076931c7e..e9875107b60 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java @@ -289,7 +289,7 @@ public class SourceHttpMessageConverter extends AbstractHttpMe private static final XMLResolver NO_OP_XML_RESOLVER = new XMLResolver() { @Override public Object resolveEntity(String publicID, String systemID, String base, String ns) { - return new ByteArrayInputStream(new byte[0]); + return StreamUtils.emptyInput(); } }; diff --git a/spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsMultipartFile.java b/spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsMultipartFile.java index aea5769344f..5e77e4c46d6 100644 --- a/spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsMultipartFile.java +++ b/spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsMultipartFile.java @@ -16,7 +16,6 @@ package org.springframework.web.multipart.commons; -import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -28,10 +27,11 @@ import org.apache.commons.fileupload.disk.DiskFileItem; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.util.StreamUtils; import org.springframework.web.multipart.MultipartFile; /** - * MultipartFile implementation for Apache Commons FileUpload. + * {@link MultipartFile} implementation for Apache Commons FileUpload. * * @author Trevor D. Cook * @author Juergen Hoeller @@ -124,7 +124,7 @@ public class CommonsMultipartFile implements MultipartFile, Serializable { throw new IllegalStateException("File has been moved - cannot be read again"); } InputStream inputStream = this.fileItem.getInputStream(); - return (inputStream != null ? inputStream : new ByteArrayInputStream(new byte[0])); + return (inputStream != null ? inputStream : StreamUtils.emptyInput()); } @Override diff --git a/spring-web/src/test/java/org/springframework/mock/web/test/MockHttpServletRequest.java b/spring-web/src/test/java/org/springframework/mock/web/test/MockHttpServletRequest.java index ff90ffd7c78..48b03112e14 100644 --- a/spring-web/src/test/java/org/springframework/mock/web/test/MockHttpServletRequest.java +++ b/spring-web/src/test/java/org/springframework/mock/web/test/MockHttpServletRequest.java @@ -39,7 +39,6 @@ import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.TimeZone; - import javax.servlet.AsyncContext; import javax.servlet.DispatcherType; import javax.servlet.RequestDispatcher; @@ -59,6 +58,7 @@ import org.springframework.util.Assert; import org.springframework.util.LinkedCaseInsensitiveMap; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; +import org.springframework.util.StreamUtils; import org.springframework.util.StringUtils; /** @@ -122,7 +122,7 @@ public class MockHttpServletRequest implements HttpServletRequest { private static final String CHARSET_PREFIX = "charset="; private static final ServletInputStream EMPTY_SERVLET_INPUT_STREAM = - new DelegatingServletInputStream(new ByteArrayInputStream(new byte[0])); + new DelegatingServletInputStream(StreamUtils.emptyInput()); /** * Date formats as specified in the HTTP RFC diff --git a/spring-web/src/test/java/org/springframework/web/filter/ShallowEtagHeaderFilterTests.java b/spring-web/src/test/java/org/springframework/web/filter/ShallowEtagHeaderFilterTests.java index ea78811f892..c6428a77526 100644 --- a/spring-web/src/test/java/org/springframework/web/filter/ShallowEtagHeaderFilterTests.java +++ b/spring-web/src/test/java/org/springframework/web/filter/ShallowEtagHeaderFilterTests.java @@ -16,16 +16,15 @@ package org.springframework.web.filter; -import java.io.ByteArrayInputStream; import javax.servlet.FilterChain; import javax.servlet.http.HttpServletResponse; -import org.junit.Before; import org.junit.Test; import org.springframework.mock.web.test.MockHttpServletRequest; import org.springframework.mock.web.test.MockHttpServletResponse; import org.springframework.util.FileCopyUtils; +import org.springframework.util.StreamUtils; import static org.junit.Assert.*; @@ -36,27 +35,23 @@ import static org.junit.Assert.*; */ public class ShallowEtagHeaderFilterTests { - private ShallowEtagHeaderFilter filter; + private final ShallowEtagHeaderFilter filter = new ShallowEtagHeaderFilter(); - @Before - public void createFilter() throws Exception { - filter = new ShallowEtagHeaderFilter(); - } @Test public void isEligibleForEtag() { MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hotels"); MockHttpServletResponse response = new MockHttpServletResponse(); - assertTrue(filter.isEligibleForEtag(request, response, 200, new ByteArrayInputStream(new byte[0]))); - assertFalse(filter.isEligibleForEtag(request, response, 300, new ByteArrayInputStream(new byte[0]))); + assertTrue(filter.isEligibleForEtag(request, response, 200, StreamUtils.emptyInput())); + assertFalse(filter.isEligibleForEtag(request, response, 300, StreamUtils.emptyInput())); request = new MockHttpServletRequest("POST", "/hotels"); - assertFalse(filter.isEligibleForEtag(request, response, 200, new ByteArrayInputStream(new byte[0]))); + assertFalse(filter.isEligibleForEtag(request, response, 200, StreamUtils.emptyInput())); request = new MockHttpServletRequest("POST", "/hotels"); request.addHeader("Cache-Control","must-revalidate, no-store"); - assertFalse(filter.isEligibleForEtag(request, response, 200, new ByteArrayInputStream(new byte[0]))); + assertFalse(filter.isEligibleForEtag(request, response, 200, StreamUtils.emptyInput())); } @Test @@ -120,9 +115,7 @@ public class ShallowEtagHeaderFilterTests { assertArrayEquals("Invalid content", new byte[0], response.getContentAsByteArray()); } - // SPR-12960 - - @Test + @Test // SPR-12960 public void filterWriterWithDisabledCaching() throws Exception { final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hotels"); MockHttpServletResponse response = new MockHttpServletResponse();