Skip to content

Commit 66177df

Browse files
committed
StreamUtils.emptyInput() for consistent empty InputStream exposure
Issue: SPR-13563
1 parent 6256586 commit 66177df

File tree

9 files changed

+36
-31
lines changed

9 files changed

+36
-31
lines changed

spring-context/src/test/java/org/springframework/scripting/support/ResourceScriptSourceTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@
1616

1717
package org.springframework.scripting.support;
1818

19-
import java.io.ByteArrayInputStream;
2019
import java.io.IOException;
2120

2221
import org.junit.Test;
2322

2423
import org.springframework.core.io.ByteArrayResource;
2524
import org.springframework.core.io.Resource;
25+
import org.springframework.util.StreamUtils;
2626

2727
import static org.junit.Assert.*;
2828
import static org.mockito.BDDMockito.*;
@@ -59,7 +59,7 @@ public void lastModifiedWorksWithResourceThatDoesNotSupportFileBasedReading() th
5959
// does not support File-based reading; delegates to InputStream-style reading...
6060
//resource.getFile();
6161
//mock.setThrowable(new FileNotFoundException());
62-
given(resource.getInputStream()).willReturn(new ByteArrayInputStream(new byte[0]));
62+
given(resource.getInputStream()).willReturn(StreamUtils.emptyInput());
6363

6464
ResourceScriptSource scriptSource = new ResourceScriptSource(resource);
6565
assertTrue("ResourceScriptSource must start off in the 'isModified' state (it obviously isn't).", scriptSource.isModified());

spring-core/src/main/java/org/springframework/util/StreamUtils.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2015 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.util;
1818

19+
import java.io.ByteArrayInputStream;
1920
import java.io.ByteArrayOutputStream;
2021
import java.io.FilterInputStream;
2122
import java.io.FilterOutputStream;
@@ -43,6 +44,8 @@ public abstract class StreamUtils {
4344

4445
public static final int BUFFER_SIZE = 4096;
4546

47+
private static final byte[] EMPTY_CONTENT = new byte[0];
48+
4649

4750
/**
4851
* Copy the contents of the given InputStream into a new byte array.
@@ -129,7 +132,16 @@ public static int copy(InputStream in, OutputStream out) throws IOException {
129132
}
130133

131134
/**
132-
* Returns a variant of the given {@link InputStream} where calling
135+
* Return an efficient empty {@link InputStream}.
136+
* @return a {@link ByteArrayInputStream} based on an empty byte array
137+
* @since 4.2.2
138+
*/
139+
public static InputStream emptyInput() {
140+
return new ByteArrayInputStream(EMPTY_CONTENT);
141+
}
142+
143+
/**
144+
* Return a variant of the given {@link InputStream} where calling
133145
* {@link InputStream#close() close()} has no effect.
134146
* @param in the InputStream to decorate
135147
* @return a version of the InputStream that ignores calls to close
@@ -140,7 +152,7 @@ public static InputStream nonClosing(InputStream in) {
140152
}
141153

142154
/**
143-
* Returns a variant of the given {@link OutputStream} where calling
155+
* Return a variant of the given {@link OutputStream} where calling
144156
* {@link OutputStream#close() close()} has no effect.
145157
* @param out the OutputStream to decorate
146158
* @return a version of the OutputStream that ignores calls to close

spring-test/src/main/java/org/springframework/mock/web/MockHttpServletRequest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
import java.util.Map;
4040
import java.util.Set;
4141
import java.util.TimeZone;
42-
4342
import javax.servlet.AsyncContext;
4443
import javax.servlet.DispatcherType;
4544
import javax.servlet.RequestDispatcher;
@@ -59,6 +58,7 @@
5958
import org.springframework.util.LinkedCaseInsensitiveMap;
6059
import org.springframework.util.LinkedMultiValueMap;
6160
import org.springframework.util.MultiValueMap;
61+
import org.springframework.util.StreamUtils;
6262
import org.springframework.util.StringUtils;
6363

6464
/**
@@ -122,7 +122,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
122122
private static final String CHARSET_PREFIX = "charset=";
123123

124124
private static final ServletInputStream EMPTY_SERVLET_INPUT_STREAM =
125-
new DelegatingServletInputStream(new ByteArrayInputStream(new byte[0]));
125+
new DelegatingServletInputStream(StreamUtils.emptyInput());
126126

127127
/**
128128
* Date formats as specified in the HTTP RFC

spring-web/src/main/java/org/springframework/http/converter/json/Jackson2ObjectMapperBuilder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
package org.springframework.http.converter.json;
1818

19-
import java.io.ByteArrayInputStream;
2019
import java.text.DateFormat;
2120
import java.text.SimpleDateFormat;
2221
import java.util.Arrays;
@@ -54,6 +53,7 @@
5453
import org.springframework.context.ApplicationContext;
5554
import org.springframework.util.Assert;
5655
import org.springframework.util.ClassUtils;
56+
import org.springframework.util.StreamUtils;
5757
import org.springframework.util.StringUtils;
5858

5959
/**
@@ -761,7 +761,7 @@ public ObjectMapper create() {
761761
private static final XMLResolver NO_OP_XML_RESOLVER = new XMLResolver() {
762762
@Override
763763
public Object resolveEntity(String publicID, String systemID, String base, String ns) {
764-
return new ByteArrayInputStream(new byte[0]);
764+
return StreamUtils.emptyInput();
765765
}
766766
};
767767
}

spring-web/src/main/java/org/springframework/http/converter/xml/Jaxb2CollectionHttpMessageConverter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
package org.springframework.http.converter.xml;
1818

19-
import java.io.ByteArrayInputStream;
2019
import java.io.IOException;
2120
import java.lang.reflect.ParameterizedType;
2221
import java.lang.reflect.Type;
@@ -46,6 +45,7 @@
4645
import org.springframework.http.converter.HttpMessageConversionException;
4746
import org.springframework.http.converter.HttpMessageNotReadableException;
4847
import org.springframework.http.converter.HttpMessageNotWritableException;
48+
import org.springframework.util.StreamUtils;
4949

5050
/**
5151
* An {@code HttpMessageConverter} that can read XML collections using JAXB2.
@@ -256,7 +256,7 @@ protected XMLInputFactory createXmlInputFactory() {
256256
private static final XMLResolver NO_OP_XML_RESOLVER = new XMLResolver() {
257257
@Override
258258
public Object resolveEntity(String publicID, String systemID, String base, String ns) {
259-
return new ByteArrayInputStream(new byte[0]);
259+
return StreamUtils.emptyInput();
260260
}
261261
};
262262

spring-web/src/main/java/org/springframework/http/converter/xml/SourceHttpMessageConverter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ public InputSource resolveEntity(String publicId, String systemId) {
289289
private static final XMLResolver NO_OP_XML_RESOLVER = new XMLResolver() {
290290
@Override
291291
public Object resolveEntity(String publicID, String systemID, String base, String ns) {
292-
return new ByteArrayInputStream(new byte[0]);
292+
return StreamUtils.emptyInput();
293293
}
294294
};
295295

spring-web/src/main/java/org/springframework/web/multipart/commons/CommonsMultipartFile.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
package org.springframework.web.multipart.commons;
1818

19-
import java.io.ByteArrayInputStream;
2019
import java.io.File;
2120
import java.io.IOException;
2221
import java.io.InputStream;
@@ -28,10 +27,11 @@
2827
import org.apache.commons.logging.Log;
2928
import org.apache.commons.logging.LogFactory;
3029

30+
import org.springframework.util.StreamUtils;
3131
import org.springframework.web.multipart.MultipartFile;
3232

3333
/**
34-
* MultipartFile implementation for Apache Commons FileUpload.
34+
* {@link MultipartFile} implementation for Apache Commons FileUpload.
3535
*
3636
* @author Trevor D. Cook
3737
* @author Juergen Hoeller
@@ -124,7 +124,7 @@ public InputStream getInputStream() throws IOException {
124124
throw new IllegalStateException("File has been moved - cannot be read again");
125125
}
126126
InputStream inputStream = this.fileItem.getInputStream();
127-
return (inputStream != null ? inputStream : new ByteArrayInputStream(new byte[0]));
127+
return (inputStream != null ? inputStream : StreamUtils.emptyInput());
128128
}
129129

130130
@Override

spring-web/src/test/java/org/springframework/mock/web/test/MockHttpServletRequest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
import java.util.Map;
4040
import java.util.Set;
4141
import java.util.TimeZone;
42-
4342
import javax.servlet.AsyncContext;
4443
import javax.servlet.DispatcherType;
4544
import javax.servlet.RequestDispatcher;
@@ -59,6 +58,7 @@
5958
import org.springframework.util.LinkedCaseInsensitiveMap;
6059
import org.springframework.util.LinkedMultiValueMap;
6160
import org.springframework.util.MultiValueMap;
61+
import org.springframework.util.StreamUtils;
6262
import org.springframework.util.StringUtils;
6363

6464
/**
@@ -122,7 +122,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
122122
private static final String CHARSET_PREFIX = "charset=";
123123

124124
private static final ServletInputStream EMPTY_SERVLET_INPUT_STREAM =
125-
new DelegatingServletInputStream(new ByteArrayInputStream(new byte[0]));
125+
new DelegatingServletInputStream(StreamUtils.emptyInput());
126126

127127
/**
128128
* Date formats as specified in the HTTP RFC

spring-web/src/test/java/org/springframework/web/filter/ShallowEtagHeaderFilterTests.java

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,15 @@
1616

1717
package org.springframework.web.filter;
1818

19-
import java.io.ByteArrayInputStream;
2019
import javax.servlet.FilterChain;
2120
import javax.servlet.http.HttpServletResponse;
2221

23-
import org.junit.Before;
2422
import org.junit.Test;
2523

2624
import org.springframework.mock.web.test.MockHttpServletRequest;
2725
import org.springframework.mock.web.test.MockHttpServletResponse;
2826
import org.springframework.util.FileCopyUtils;
27+
import org.springframework.util.StreamUtils;
2928

3029
import static org.junit.Assert.*;
3130

@@ -36,27 +35,23 @@
3635
*/
3736
public class ShallowEtagHeaderFilterTests {
3837

39-
private ShallowEtagHeaderFilter filter;
38+
private final ShallowEtagHeaderFilter filter = new ShallowEtagHeaderFilter();
4039

41-
@Before
42-
public void createFilter() throws Exception {
43-
filter = new ShallowEtagHeaderFilter();
44-
}
4540

4641
@Test
4742
public void isEligibleForEtag() {
4843
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hotels");
4944
MockHttpServletResponse response = new MockHttpServletResponse();
5045

51-
assertTrue(filter.isEligibleForEtag(request, response, 200, new ByteArrayInputStream(new byte[0])));
52-
assertFalse(filter.isEligibleForEtag(request, response, 300, new ByteArrayInputStream(new byte[0])));
46+
assertTrue(filter.isEligibleForEtag(request, response, 200, StreamUtils.emptyInput()));
47+
assertFalse(filter.isEligibleForEtag(request, response, 300, StreamUtils.emptyInput()));
5348

5449
request = new MockHttpServletRequest("POST", "/hotels");
55-
assertFalse(filter.isEligibleForEtag(request, response, 200, new ByteArrayInputStream(new byte[0])));
50+
assertFalse(filter.isEligibleForEtag(request, response, 200, StreamUtils.emptyInput()));
5651

5752
request = new MockHttpServletRequest("POST", "/hotels");
5853
request.addHeader("Cache-Control","must-revalidate, no-store");
59-
assertFalse(filter.isEligibleForEtag(request, response, 200, new ByteArrayInputStream(new byte[0])));
54+
assertFalse(filter.isEligibleForEtag(request, response, 200, StreamUtils.emptyInput()));
6055
}
6156

6257
@Test
@@ -120,9 +115,7 @@ public void filterWriter() throws Exception {
120115
assertArrayEquals("Invalid content", new byte[0], response.getContentAsByteArray());
121116
}
122117

123-
// SPR-12960
124-
125-
@Test
118+
@Test // SPR-12960
126119
public void filterWriterWithDisabledCaching() throws Exception {
127120
final MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hotels");
128121
MockHttpServletResponse response = new MockHttpServletResponse();

0 commit comments

Comments
 (0)