From dd7f54c3c06ba4da673634d9dc3c456fb343cb67 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 24 Mar 2014 22:57:38 +0100 Subject: [PATCH] Revised ResizableByteArrayOutputStream as an actual subclass of ByteArrayOutputStream, and consistently applied appropriate ByteArrayOutputStream initial capacities across the codebase Issue: SPR-11594 --- .../support/PropertiesToStringConverter.java | 4 +- .../support/SerializingConverter.java | 4 +- .../core/style/ToStringCreator.java | 8 +- .../util/ResizableByteArrayOutputStream.java | 148 +++++------------- .../util/SerializationUtils.java | 4 +- .../ResizableByteArrayOutputStreamTests.java | 41 ++--- .../MappingJackson2MessageConverter.java | 4 +- .../MappingJacksonMessageConverter.java | 4 +- .../MarshallingMessageConverter.java | 4 +- .../MappingJackson2MessageConverter.java | 2 +- .../messaging/simp/stomp/StompDecoder.java | 19 +-- .../messaging/simp/stomp/StompEncoder.java | 21 +-- .../oxm/jibx/JibxMarshaller.java | 4 +- .../mock/http/MockHttpOutputMessage.java | 6 +- .../mock/web/MockHttpServletResponse.java | 11 +- .../mock/web/portlet/MockMimeResponse.java | 27 ++-- ...stractBufferingAsyncClientHttpRequest.java | 2 +- .../AbstractBufferingClientHttpRequest.java | 2 +- .../ByteArrayHttpMessageConverter.java | 11 +- .../http/server/ServletServerHttpRequest.java | 4 +- .../filter/AbstractRequestLoggingFilter.java | 48 +++--- .../web/filter/ShallowEtagHeaderFilter.java | 18 +-- .../web/servlet/view/xml/MarshallingView.java | 2 +- 23 files changed, 165 insertions(+), 233 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/PropertiesToStringConverter.java b/spring-core/src/main/java/org/springframework/core/convert/support/PropertiesToStringConverter.java index 5417a62659e..4d2124ad141 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/support/PropertiesToStringConverter.java +++ b/spring-core/src/main/java/org/springframework/core/convert/support/PropertiesToStringConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 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. @@ -34,7 +34,7 @@ final class PropertiesToStringConverter implements Converter @Override public String convert(Properties source) { try { - ByteArrayOutputStream os = new ByteArrayOutputStream(); + ByteArrayOutputStream os = new ByteArrayOutputStream(256); source.store(os, null); return os.toString("ISO-8859-1"); } diff --git a/spring-core/src/main/java/org/springframework/core/serializer/support/SerializingConverter.java b/spring-core/src/main/java/org/springframework/core/serializer/support/SerializingConverter.java index b092cc7bd14..1a35c6a2b51 100644 --- a/spring-core/src/main/java/org/springframework/core/serializer/support/SerializingConverter.java +++ b/spring-core/src/main/java/org/springframework/core/serializer/support/SerializingConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 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. @@ -57,7 +57,7 @@ public class SerializingConverter implements Converter { */ @Override public byte[] convert(Object source) { - ByteArrayOutputStream byteStream = new ByteArrayOutputStream(128); + ByteArrayOutputStream byteStream = new ByteArrayOutputStream(256); try { this.serializer.serialize(source, byteStream); return byteStream.toByteArray(); diff --git a/spring-core/src/main/java/org/springframework/core/style/ToStringCreator.java b/spring-core/src/main/java/org/springframework/core/style/ToStringCreator.java index 5871f8dfccf..6f682939cc7 100644 --- a/spring-core/src/main/java/org/springframework/core/style/ToStringCreator.java +++ b/spring-core/src/main/java/org/springframework/core/style/ToStringCreator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 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. @@ -36,11 +36,11 @@ public class ToStringCreator { new DefaultToStringStyler(StylerUtils.DEFAULT_VALUE_STYLER); - private StringBuilder buffer = new StringBuilder(512); + private final StringBuilder buffer = new StringBuilder(256); - private ToStringStyler styler; + private final ToStringStyler styler; - private Object object; + private final Object object; private boolean styledFirstField; diff --git a/spring-core/src/main/java/org/springframework/util/ResizableByteArrayOutputStream.java b/spring-core/src/main/java/org/springframework/util/ResizableByteArrayOutputStream.java index 727c55b8688..82081bb928c 100644 --- a/spring-core/src/main/java/org/springframework/util/ResizableByteArrayOutputStream.java +++ b/spring-core/src/main/java/org/springframework/util/ResizableByteArrayOutputStream.java @@ -13,143 +13,79 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.util; -import java.io.IOException; -import java.io.OutputStream; +import java.io.ByteArrayOutputStream; /** - * A variation of {@link java.io.ByteArrayOutputStream} that: + * An extension of {@link java.io.ByteArrayOutputStream} that: *
    - *
  • has public {@link org.springframework.util.ResizableByteArrayOutputStream#grow(int)} and - * {@link org.springframework.util.ResizableByteArrayOutputStream#resize(int)} methods to get more control - * over the the size of the internal buffer
  • - *
  • does not synchronize on buffer access - so this class should not be used if concurrent access - * to the buffer is expected
  • + *
  • has public {@link org.springframework.util.ResizableByteArrayOutputStream#grow(int)} + * and {@link org.springframework.util.ResizableByteArrayOutputStream#resize(int)} methods + * to get more control over the the size of the internal buffer
  • + *
  • has a higher initial capacity (256) by default
  • *
* * @author Brian Clozel + * @author Juergen Hoeller * @since 4.0 */ -public class ResizableByteArrayOutputStream extends OutputStream { +public class ResizableByteArrayOutputStream extends ByteArrayOutputStream { - private static final int INITIAL_BUFFER_SIZE = 32; + private static final int DEFAULT_INITIAL_CAPACITY = 256; - protected byte[] buffer; - - protected int count; /** - * Create a new ByteArrayOutputStream with the default buffer size of 32 bytes. + * Create a new ResizableByteArrayOutputStream + * with the default initial capacity of 128 bytes. */ public ResizableByteArrayOutputStream() { - this(INITIAL_BUFFER_SIZE); + super(DEFAULT_INITIAL_CAPACITY); } /** - * Create a new ByteArrayOutputStream with a specified initial buffer size. - * - * @param size The initial buffer size in bytes + * Create a new ResizableByteArrayOutputStream + * with the specified initial capacity. + * @param initialCapacity the initial buffer size in bytes */ - public ResizableByteArrayOutputStream(int size) { - buffer = new byte[size]; - count = 0; + public ResizableByteArrayOutputStream(int initialCapacity) { + super(initialCapacity); } - /** - * Return the size of the internal buffer. - */ - public int size() { - return buffer.length; - } /** - * Return the number of bytes that have been written to the buffer so far. - */ - public int count() { - return count; - } - - /** - * Discard all bytes written to the internal buffer by setting the count variable to 0. - */ - public void reset() { - count = 0; - } - - /** - * Grow the internal buffer size - * @param add number of bytes to add to the current buffer size + * Resize the internal buffer size to a specified capacity. + * @param targetCapacity the desired size of the buffer + * @throws IllegalArgumentException if the given capacity is smaller than + * the actual size of the content stored in the buffer already * @see ResizableByteArrayOutputStream#size() */ - public void grow(int add) { - if (count + add > buffer.length) { - int newlen = Math.max(buffer.length * 2, count + add); - resize(newlen); + public synchronized void resize(int targetCapacity) { + Assert.isTrue(targetCapacity >= this.count, "New capacity must not be smaller than current size"); + byte[] resizedBuffer = new byte[targetCapacity]; + System.arraycopy(this.buf, 0, resizedBuffer, 0, this.count); + this.buf = resizedBuffer; + } + + /** + * Grow the internal buffer size. + * @param additionalCapacity the number of bytes to add to the current buffer size + * @see ResizableByteArrayOutputStream#size() + */ + public synchronized void grow(int additionalCapacity) { + Assert.isTrue(additionalCapacity >= 0, "Additional capacity must be 0 or higher"); + if (this.count + additionalCapacity > this.buf.length) { + int newCapacity = Math.max(this.buf.length * 2, this.count + additionalCapacity); + resize(newCapacity); } } /** - * Resize the internal buffer size to a specified value - * @param size the size of the buffer - * @throws java.lang.IllegalArgumentException if the given size is - * smaller than the actual size of the content stored in the buffer - * @see ResizableByteArrayOutputStream#size() + * Return the current size of this stream's internal buffer. */ - public void resize(int size) { - Assert.isTrue(size >= count); - - byte[] newbuf = new byte[size]; - System.arraycopy(buffer, 0, newbuf, 0, count); - buffer = newbuf; - } - - /** - * Write the specified byte into the internal buffer, thus incrementing the - * {{@link org.springframework.util.ResizableByteArrayOutputStream#count()}} - * @param oneByte the byte to be written in the buffer - * @see ResizableByteArrayOutputStream#count() - */ - public void write(int oneByte) { - grow(1); - buffer[count++] = (byte) oneByte; - } - - /** - * Write add bytes from the passed in array - * inBuffer starting at index offset into the - * internal buffer. - * - * @param inBuffer The byte array to write data from - * @param offset The index into the buffer to start writing data from - * @param add The number of bytes to write - * @see ResizableByteArrayOutputStream#count() - */ - public void write(byte[] inBuffer, int offset, int add) { - if (add >= 0) { - grow(add); - } - System.arraycopy(inBuffer, offset, buffer, count, add); - count += add; - } - - /** - * Write all bytes that have been written to the specified OutputStream. - * - * @param out The OutputStream to write to - * @exception IOException If an error occurs - */ - public void writeTo(OutputStream out) throws IOException { - out.write(buffer, 0, count); - } - - /** - * Return a byte array containing the bytes that have been written to this stream so far. - */ - public byte[] toByteArray() { - byte[] ret = new byte[count]; - System.arraycopy(buffer, 0, ret, 0, count); - return ret; + public synchronized int capacity() { + return this.buf.length; } } diff --git a/spring-core/src/main/java/org/springframework/util/SerializationUtils.java b/spring-core/src/main/java/org/springframework/util/SerializationUtils.java index 943996702d0..f85b1c72dd4 100644 --- a/spring-core/src/main/java/org/springframework/util/SerializationUtils.java +++ b/spring-core/src/main/java/org/springframework/util/SerializationUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2014 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. @@ -39,7 +39,7 @@ public abstract class SerializationUtils { if (object == null) { return null; } - ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(1024); try { ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(object); diff --git a/spring-core/src/test/java/org/springframework/util/ResizableByteArrayOutputStreamTests.java b/spring-core/src/test/java/org/springframework/util/ResizableByteArrayOutputStreamTests.java index e5ec17bb849..ec41e815f34 100644 --- a/spring-core/src/test/java/org/springframework/util/ResizableByteArrayOutputStreamTests.java +++ b/spring-core/src/test/java/org/springframework/util/ResizableByteArrayOutputStreamTests.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.util; import org.junit.Before; @@ -22,56 +23,56 @@ import static org.junit.Assert.*; /** * @author Brian Clozel + * @author Juergen Hoeller */ public class ResizableByteArrayOutputStreamTests { - private ResizableByteArrayOutputStream baos; + private static final int INITIAL_CAPACITY = 256; - private String helloString; + private ResizableByteArrayOutputStream baos; private byte[] helloBytes; - private static final int INITIAL_SIZE = 32; @Before public void setUp() throws Exception { - this.baos = new ResizableByteArrayOutputStream(INITIAL_SIZE); - this.helloString = "Hello World"; - this.helloBytes = helloString.getBytes("UTF-8"); + this.baos = new ResizableByteArrayOutputStream(INITIAL_CAPACITY); + this.helloBytes = "Hello World".getBytes("UTF-8"); } + @Test public void resize() throws Exception { - assertEquals(INITIAL_SIZE, this.baos.buffer.length); + assertEquals(INITIAL_CAPACITY, this.baos.capacity()); this.baos.write(helloBytes); int size = 64; this.baos.resize(size); - assertEquals(size, this.baos.buffer.length); - assertByteArrayEqualsString(helloString, this.baos); + assertEquals(size, this.baos.capacity()); + assertByteArrayEqualsString(this.baos); } @Test public void autoGrow() { - assertEquals(INITIAL_SIZE, this.baos.buffer.length); - for(int i= 0; i < 33; i++) { + assertEquals(INITIAL_CAPACITY, this.baos.capacity()); + for(int i = 0; i < 129; i++) { this.baos.write(0); } - assertEquals(64, this.baos.buffer.length); + assertEquals(256, this.baos.capacity()); } @Test public void grow() throws Exception { - assertEquals(INITIAL_SIZE, this.baos.buffer.length); + assertEquals(INITIAL_CAPACITY, this.baos.capacity()); this.baos.write(helloBytes); - this.baos.grow(100); - assertEquals(this.helloString.length() + 100, this.baos.buffer.length); - assertByteArrayEqualsString(helloString, this.baos); + this.baos.grow(1000); + assertEquals(this.helloBytes.length + 1000, this.baos.capacity()); + assertByteArrayEqualsString(this.baos); } @Test public void write() throws Exception{ this.baos.write(helloBytes); - assertByteArrayEqualsString(helloString, this.baos); + assertByteArrayEqualsString(this.baos); } @Test(expected = IllegalArgumentException.class) @@ -80,9 +81,9 @@ public class ResizableByteArrayOutputStreamTests { this.baos.resize(5); } - private void assertByteArrayEqualsString(String expected, ResizableByteArrayOutputStream actual) { - String actualString = new String(actual.buffer, 0, actual.count()); - assertEquals(expected, actualString); + + private void assertByteArrayEqualsString(ResizableByteArrayOutputStream actual) { + assertArrayEquals(helloBytes, actual.toByteArray()); } } diff --git a/spring-jms/src/main/java/org/springframework/jms/support/converter/MappingJackson2MessageConverter.java b/spring-jms/src/main/java/org/springframework/jms/support/converter/MappingJackson2MessageConverter.java index 28418fd10be..59a5b6c0029 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/converter/MappingJackson2MessageConverter.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/converter/MappingJackson2MessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -218,7 +218,7 @@ public class MappingJackson2MessageConverter implements MessageConverter, BeanCl protected BytesMessage mapToBytesMessage(Object object, Session session, ObjectMapper objectMapper) throws JMSException, IOException { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ByteArrayOutputStream bos = new ByteArrayOutputStream(1024); OutputStreamWriter writer = new OutputStreamWriter(bos, this.encoding); objectMapper.writeValue(writer, object); diff --git a/spring-jms/src/main/java/org/springframework/jms/support/converter/MappingJacksonMessageConverter.java b/spring-jms/src/main/java/org/springframework/jms/support/converter/MappingJacksonMessageConverter.java index 28489b3b633..1bcec4465b7 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/converter/MappingJacksonMessageConverter.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/converter/MappingJacksonMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -221,7 +221,7 @@ public class MappingJacksonMessageConverter implements MessageConverter, BeanCla protected BytesMessage mapToBytesMessage(Object object, Session session, ObjectMapper objectMapper) throws JMSException, IOException { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ByteArrayOutputStream bos = new ByteArrayOutputStream(1024); OutputStreamWriter writer = new OutputStreamWriter(bos, this.encoding); objectMapper.writeValue(writer, object); diff --git a/spring-jms/src/main/java/org/springframework/jms/support/converter/MarshallingMessageConverter.java b/spring-jms/src/main/java/org/springframework/jms/support/converter/MarshallingMessageConverter.java index 9cdaaae3622..8fa6fb1e74e 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/converter/MarshallingMessageConverter.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/converter/MarshallingMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 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. @@ -231,7 +231,7 @@ public class MarshallingMessageConverter implements MessageConverter, Initializi protected BytesMessage marshalToBytesMessage(Object object, Session session, Marshaller marshaller) throws JMSException, IOException, XmlMappingException { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ByteArrayOutputStream bos = new ByteArrayOutputStream(1024); StreamResult streamResult = new StreamResult(bos); marshaller.marshal(object, streamResult); BytesMessage message = session.createBytesMessage(); diff --git a/spring-messaging/src/main/java/org/springframework/messaging/converter/MappingJackson2MessageConverter.java b/spring-messaging/src/main/java/org/springframework/messaging/converter/MappingJackson2MessageConverter.java index 12531d29303..dc99360ca00 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/converter/MappingJackson2MessageConverter.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/converter/MappingJackson2MessageConverter.java @@ -181,7 +181,7 @@ public class MappingJackson2MessageConverter extends AbstractMessageConverter { public Object convertToInternal(Object payload, MessageHeaders headers) { try { if (byte[].class.equals(getSerializedPayloadClass())) { - ByteArrayOutputStream out = new ByteArrayOutputStream(); + ByteArrayOutputStream out = new ByteArrayOutputStream(1024); JsonEncoding encoding = getJsonEncoding(getMimeType(headers)); // The following has been deprecated as late as Jackson 2.2 (April 2013); diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompDecoder.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompDecoder.java index b6449649460..11c80f845d9 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompDecoder.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompDecoder.java @@ -28,7 +28,6 @@ import org.springframework.messaging.simp.SimpMessageType; import org.springframework.messaging.support.MessageBuilder; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; -import org.springframework.util.StringUtils; /** * Decodes STOMP frames from a {@link ByteBuffer}. If the buffer does not contain @@ -52,20 +51,15 @@ public class StompDecoder { * Decodes a STOMP frame in the given {@code buffer} into a {@link Message}. * If the given ByteBuffer contains partial STOMP frame content, the method * resets the buffer and returns {@code null}. - * - * @param buffer The buffer to decode the frame from - * - * @return The decoded message or {@code null} + * @param buffer the buffer to decode the frame from + * @return the decoded message or {@code null} */ public Message decode(ByteBuffer buffer) { - Message decodedMessage = null; - skipLeadingEol(buffer); buffer.mark(); String command = readCommand(buffer); - if (command.length() > 0) { MultiValueMap headers = readHeaders(buffer); byte[] payload = readPayload(buffer, headers); @@ -108,7 +102,7 @@ public class StompDecoder { } private String readCommand(ByteBuffer buffer) { - ByteArrayOutputStream command = new ByteArrayOutputStream(); + ByteArrayOutputStream command = new ByteArrayOutputStream(256); while (buffer.remaining() > 0 && !isEol(buffer)) { command.write(buffer.get()); } @@ -118,7 +112,7 @@ public class StompDecoder { private MultiValueMap readHeaders(ByteBuffer buffer) { MultiValueMap headers = new LinkedMultiValueMap(); while (true) { - ByteArrayOutputStream headerStream = new ByteArrayOutputStream(); + ByteArrayOutputStream headerStream = new ByteArrayOutputStream(256); while (buffer.remaining() > 0 && !isEol(buffer)) { headerStream.write(buffer.get()); } @@ -176,7 +170,7 @@ public class StompDecoder { } } else { - ByteArrayOutputStream payload = new ByteArrayOutputStream(); + ByteArrayOutputStream payload = new ByteArrayOutputStream(256); while (buffer.remaining() > 0) { byte b = buffer.get(); if (b == 0) { @@ -208,4 +202,5 @@ public class StompDecoder { } return false; } -} \ No newline at end of file + +} diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompEncoder.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompEncoder.java index d41f0fa102f..e7f94ddd9e9 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompEncoder.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -26,6 +26,7 @@ import java.util.Map.Entry; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.messaging.Message; import org.springframework.messaging.simp.SimpMessageType; @@ -45,23 +46,22 @@ public final class StompEncoder { private final Log logger = LogFactory.getLog(StompEncoder.class); + /** * Encodes the given STOMP {@code message} into a {@code byte[]} - * - * @param message The message to encode - * - * @return The encoded message + * @param message the message to encode + * @return the encoded message */ public byte[] encode(Message message) { try { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(256); DataOutputStream output = new DataOutputStream(baos); StompHeaderAccessor headers = StompHeaderAccessor.wrap(message); - if (isHeartbeat(headers)) { output.write(message.getPayload()); - } else { + } + else { writeCommand(headers, output); writeHeaders(headers, message, output); output.write(LF); @@ -77,7 +77,7 @@ public final class StompEncoder { } private boolean isHeartbeat(StompHeaderAccessor headers) { - return headers.getMessageType() == SimpMessageType.HEARTBEAT; + return (headers.getMessageType() == SimpMessageType.HEARTBEAT); } private void writeCommand(StompHeaderAccessor headers, DataOutputStream output) throws IOException { @@ -132,4 +132,5 @@ public final class StompEncoder { .replaceAll("\n", "\\\\n") .replaceAll("\r", "\\\\r"); } -} \ No newline at end of file + +} diff --git a/spring-oxm/src/main/java/org/springframework/oxm/jibx/JibxMarshaller.java b/spring-oxm/src/main/java/org/springframework/oxm/jibx/JibxMarshaller.java index 715ef4e2356..860d79125ea 100644 --- a/spring-oxm/src/main/java/org/springframework/oxm/jibx/JibxMarshaller.java +++ b/spring-oxm/src/main/java/org/springframework/oxm/jibx/JibxMarshaller.java @@ -336,7 +336,7 @@ public class JibxMarshaller extends AbstractMarshaller implements InitializingBe private void transformAndMarshal(Object graph, Result result) throws IOException { try { - ByteArrayOutputStream os = new ByteArrayOutputStream(); + ByteArrayOutputStream os = new ByteArrayOutputStream(1024); marshalOutputStream(graph, os); ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); Transformer transformer = this.transformerFactory.newTransformer(); @@ -424,7 +424,7 @@ public class JibxMarshaller extends AbstractMarshaller implements InitializingBe if (encoding != null) { transformer.setOutputProperty(OutputKeys.ENCODING, encoding); } - ByteArrayOutputStream os = new ByteArrayOutputStream(); + ByteArrayOutputStream os = new ByteArrayOutputStream(1024); transformer.transform(source, new StreamResult(os)); ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray()); return unmarshalInputStream(is); diff --git a/spring-test/src/main/java/org/springframework/mock/http/MockHttpOutputMessage.java b/spring-test/src/main/java/org/springframework/mock/http/MockHttpOutputMessage.java index 8f31f553bbd..dc1648e9d8a 100644 --- a/spring-test/src/main/java/org/springframework/mock/http/MockHttpOutputMessage.java +++ b/spring-test/src/main/java/org/springframework/mock/http/MockHttpOutputMessage.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 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. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.mock.http; import java.io.ByteArrayOutputStream; @@ -36,7 +37,7 @@ public class MockHttpOutputMessage implements HttpOutputMessage { private final HttpHeaders headers = new HttpHeaders(); - private final ByteArrayOutputStream body = new ByteArrayOutputStream(); + private final ByteArrayOutputStream body = new ByteArrayOutputStream(1024); /** @@ -76,7 +77,6 @@ public class MockHttpOutputMessage implements HttpOutputMessage { public String getBodyAsString(Charset charset) { byte[] bytes = getBodyAsBytes(); try { - // Use return new String(bytes, charset.name()); } catch (UnsupportedEncodingException ex) { diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java b/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java index 17d5fcf08c4..395442fee68 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -71,7 +71,7 @@ public class MockHttpServletResponse implements HttpServletResponse { private boolean charset = false; - private final ByteArrayOutputStream content = new ByteArrayOutputStream(); + private final ByteArrayOutputStream content = new ByteArrayOutputStream(1024); private final ServletOutputStream outputStream = new ResponseServletOutputStream(this.content); @@ -189,8 +189,8 @@ public class MockHttpServletResponse implements HttpServletResponse { public String getContentAsString() throws UnsupportedEncodingException { flushBuffer(); - return (this.characterEncoding != null) ? - this.content.toString(this.characterEncoding) : this.content.toString(); + return (this.characterEncoding != null ? + this.content.toString(this.characterEncoding) : this.content.toString()); } @Override @@ -218,8 +218,7 @@ public class MockHttpServletResponse implements HttpServletResponse { if (contentType != null) { int charsetIndex = contentType.toLowerCase().indexOf(CHARSET_PREFIX); if (charsetIndex != -1) { - String encoding = contentType.substring(charsetIndex + CHARSET_PREFIX.length()); - this.characterEncoding = encoding; + this.characterEncoding = contentType.substring(charsetIndex + CHARSET_PREFIX.length()); this.charset = true; } updateContentTypeHeader(); diff --git a/spring-test/src/main/java/org/springframework/mock/web/portlet/MockMimeResponse.java b/spring-test/src/main/java/org/springframework/mock/web/portlet/MockMimeResponse.java index 0a48975f691..3a45fcf2097 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/portlet/MockMimeResponse.java +++ b/spring-test/src/main/java/org/springframework/mock/web/portlet/MockMimeResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 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. @@ -56,7 +56,7 @@ public class MockMimeResponse extends MockPortletResponse implements MimeRespons private int bufferSize = 4096; - private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(1024); private final CacheControl cacheControl = new MockCacheControl(); @@ -130,9 +130,9 @@ public class MockMimeResponse extends MockPortletResponse implements MimeRespons @Override public PrintWriter getWriter() throws UnsupportedEncodingException { if (this.writer == null) { - Writer targetWriter = (this.characterEncoding != null - ? new OutputStreamWriter(this.outputStream, this.characterEncoding) - : new OutputStreamWriter(this.outputStream)); + Writer targetWriter = (this.characterEncoding != null ? + new OutputStreamWriter(this.outputStream, this.characterEncoding) : + new OutputStreamWriter(this.outputStream)); this.writer = new PrintWriter(targetWriter); } return this.writer; @@ -145,9 +145,8 @@ public class MockMimeResponse extends MockPortletResponse implements MimeRespons public String getContentAsString() throws UnsupportedEncodingException { flushBuffer(); - return (this.characterEncoding != null) - ? this.outputStream.toString(this.characterEncoding) - : this.outputStream.toString(); + return (this.characterEncoding != null ? + this.outputStream.toString(this.characterEncoding) : this.outputStream.toString()); } public void setLocale(Locale locale) { @@ -174,13 +173,11 @@ public class MockMimeResponse extends MockPortletResponse implements MimeRespons if (this.writer != null) { this.writer.flush(); } - if (this.outputStream != null) { - try { - this.outputStream.flush(); - } - catch (IOException ex) { - throw new IllegalStateException("Could not flush OutputStream: " + ex.getMessage()); - } + try { + this.outputStream.flush(); + } + catch (IOException ex) { + throw new IllegalStateException("Could not flush OutputStream: " + ex.getMessage()); } this.committed = true; } diff --git a/spring-web/src/main/java/org/springframework/http/client/AbstractBufferingAsyncClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/AbstractBufferingAsyncClientHttpRequest.java index a9bedf98794..cf83983de59 100644 --- a/spring-web/src/main/java/org/springframework/http/client/AbstractBufferingAsyncClientHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/client/AbstractBufferingAsyncClientHttpRequest.java @@ -32,7 +32,7 @@ import org.springframework.util.concurrent.ListenableFuture; */ abstract class AbstractBufferingAsyncClientHttpRequest extends AbstractAsyncClientHttpRequest { - private ByteArrayOutputStream bufferedOutput = new ByteArrayOutputStream(); + private ByteArrayOutputStream bufferedOutput = new ByteArrayOutputStream(1024); @Override diff --git a/spring-web/src/main/java/org/springframework/http/client/AbstractBufferingClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/AbstractBufferingClientHttpRequest.java index ab44d94a0a4..4af73487984 100644 --- a/spring-web/src/main/java/org/springframework/http/client/AbstractBufferingClientHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/client/AbstractBufferingClientHttpRequest.java @@ -31,7 +31,7 @@ import org.springframework.http.HttpHeaders; */ abstract class AbstractBufferingClientHttpRequest extends AbstractClientHttpRequest { - private ByteArrayOutputStream bufferedOutput = new ByteArrayOutputStream(); + private ByteArrayOutputStream bufferedOutput = new ByteArrayOutputStream(1024); @Override diff --git a/spring-web/src/main/java/org/springframework/http/converter/ByteArrayHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/ByteArrayHttpMessageConverter.java index e4f801f5040..800a9febaa3 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/ByteArrayHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/ByteArrayHttpMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -27,9 +27,9 @@ import org.springframework.util.StreamUtils; /** * Implementation of {@link HttpMessageConverter} that can read and write byte arrays. * - *

By default, this converter supports all media types ({@code */*}), and writes with a {@code - * Content-Type} of {@code application/octet-stream}. This can be overridden by setting the {@link - * #setSupportedMediaTypes(java.util.List) supportedMediaTypes} property. + *

By default, this converter supports all media types ({@code */*}), and + * writes with a {@code Content-Type} of {@code application/octet-stream}. This can be + * overridden by setting the {@link #setSupportedMediaTypes supportedMediaTypes} property. * * @author Arjen Poutsma * @since 3.0 @@ -49,7 +49,8 @@ public class ByteArrayHttpMessageConverter extends AbstractHttpMessageConverter< @Override public byte[] readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException { long contentLength = inputMessage.getHeaders().getContentLength(); - ByteArrayOutputStream bos = new ByteArrayOutputStream(contentLength >= 0 ? (int) contentLength : StreamUtils.BUFFER_SIZE); + ByteArrayOutputStream bos = + new ByteArrayOutputStream(contentLength >= 0 ? (int) contentLength : StreamUtils.BUFFER_SIZE); StreamUtils.copy(inputMessage.getBody(), bos); return bos.toByteArray(); } diff --git a/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java b/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java index 9195452e84e..cd4d366ffc7 100644 --- a/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/server/ServletServerHttpRequest.java @@ -34,7 +34,6 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; - import javax.servlet.http.HttpServletRequest; import org.springframework.http.HttpHeaders; @@ -56,6 +55,7 @@ public class ServletServerHttpRequest implements ServerHttpRequest { private static final String METHOD_POST = "POST"; + private final HttpServletRequest servletRequest; private HttpHeaders headers; @@ -167,7 +167,7 @@ public class ServletServerHttpRequest implements ServerHttpRequest { * to access a parameter thus causing the input stream to be "consumed". */ private InputStream getBodyFromServletRequestParameters(HttpServletRequest request) throws IOException { - ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ByteArrayOutputStream bos = new ByteArrayOutputStream(1024); Writer writer = new OutputStreamWriter(bos, FORM_CHARSET); Map form = request.getParameterMap(); diff --git a/spring-web/src/main/java/org/springframework/web/filter/AbstractRequestLoggingFilter.java b/spring-web/src/main/java/org/springframework/web/filter/AbstractRequestLoggingFilter.java index 03c15891d7b..b68f10e8d75 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/AbstractRequestLoggingFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/AbstractRequestLoggingFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 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. @@ -21,7 +21,6 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; - import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletInputStream; @@ -53,9 +52,9 @@ import org.springframework.web.util.WebUtils; * @author Rob Harrop * @author Juergen Hoeller * @author Rossen Stoyanchev + * @since 1.2.5 * @see #beforeRequest * @see #afterRequest - * @since 1.2.5 */ public abstract class AbstractRequestLoggingFilter extends OncePerRequestFilter { @@ -69,6 +68,7 @@ public abstract class AbstractRequestLoggingFilter extends OncePerRequestFilter private static final int DEFAULT_MAX_PAYLOAD_LENGTH = 50; + private boolean includeQueryString = false; private boolean includeClientInfo = false; @@ -85,6 +85,7 @@ public abstract class AbstractRequestLoggingFilter extends OncePerRequestFilter private String afterMessageSuffix = DEFAULT_AFTER_MESSAGE_SUFFIX; + /** * Set whether or not the query string should be included in the log message.

Should be configured using an * {@code <init-param>} for parameter name "includeQueryString" in the filter definition in @@ -177,6 +178,7 @@ public abstract class AbstractRequestLoggingFilter extends OncePerRequestFilter this.afterMessageSuffix = afterMessageSuffix; } + /** * The default value is "false" so that the filter may log a "before" message * at the start of request processing and an "after" message at the end from @@ -188,9 +190,8 @@ public abstract class AbstractRequestLoggingFilter extends OncePerRequestFilter } /** - * Forwards the request to the next filter in the chain and delegates down to the subclasses to perform the actual - * request logging both before and after the request is processed. - * + * Forwards the request to the next filter in the chain and delegates down to the subclasses + * to perform the actual request logging both before and after the request is processed. * @see #beforeRequest * @see #afterRequest */ @@ -221,7 +222,6 @@ public abstract class AbstractRequestLoggingFilter extends OncePerRequestFilter /** * Get the message to write to the log before the request. - * * @see #createMessage */ private String getBeforeMessage(HttpServletRequest request) { @@ -230,7 +230,6 @@ public abstract class AbstractRequestLoggingFilter extends OncePerRequestFilter /** * Get the message to write to the log after the request. - * * @see #createMessage */ private String getAfterMessage(HttpServletRequest request) { @@ -238,10 +237,12 @@ public abstract class AbstractRequestLoggingFilter extends OncePerRequestFilter } /** - * Create a log message for the given request, prefix and suffix.

If {@code includeQueryString} is - * {@code true} then the inner part of the log message will take the form {@code request_uri?query_string} - * otherwise the message will simply be of the form {@code request_uri}.

The final message is composed of the - * inner part as described and the supplied prefix and suffix. + * Create a log message for the given request, prefix and suffix. + *

If {@code includeQueryString} is {@code true}, then the inner part + * of the log message will take the form {@code request_uri?query_string}; + * otherwise the message will simply be of the form {@code request_uri}. + *

The final message is composed of the inner part as described and + * the supplied prefix and suffix. */ protected String createMessage(HttpServletRequest request, String prefix, String suffix) { StringBuilder msg = new StringBuilder(); @@ -285,16 +286,16 @@ public abstract class AbstractRequestLoggingFilter extends OncePerRequestFilter } /** - * Concrete subclasses should implement this method to write a log message before the request is processed. - * + * Concrete subclasses should implement this method to write a log message + * before the request is processed. * @param request current HTTP request * @param message the message to log */ protected abstract void beforeRequest(HttpServletRequest request, String message); /** - * Concrete subclasses should implement this method to write a log message after the request is processed. - * + * Concrete subclasses should implement this method to write a log message + * after the request is processed. * @param request current HTTP request * @param message the message to log */ @@ -303,7 +304,7 @@ public abstract class AbstractRequestLoggingFilter extends OncePerRequestFilter private static class RequestCachingRequestWrapper extends HttpServletRequestWrapper { - private final ByteArrayOutputStream bos = new ByteArrayOutputStream(); + private final ByteArrayOutputStream bos = new ByteArrayOutputStream(1024); private final ServletInputStream inputStream; @@ -316,19 +317,19 @@ public abstract class AbstractRequestLoggingFilter extends OncePerRequestFilter @Override public ServletInputStream getInputStream() throws IOException { - return inputStream; + return this.inputStream; } @Override public String getCharacterEncoding() { - return super.getCharacterEncoding() != null ? super.getCharacterEncoding() : - WebUtils.DEFAULT_CHARACTER_ENCODING; + String enc = super.getCharacterEncoding(); + return (enc != null ? enc : WebUtils.DEFAULT_CHARACTER_ENCODING); } @Override public BufferedReader getReader() throws IOException { if (this.reader == null) { - this.reader = new BufferedReader(new InputStreamReader(inputStream, getCharacterEncoding())); + this.reader = new BufferedReader(new InputStreamReader(this.inputStream, getCharacterEncoding())); } return this.reader; } @@ -337,17 +338,18 @@ public abstract class AbstractRequestLoggingFilter extends OncePerRequestFilter return this.bos.toByteArray(); } + private class RequestCachingInputStream extends ServletInputStream { private final ServletInputStream is; - private RequestCachingInputStream(ServletInputStream is) { + public RequestCachingInputStream(ServletInputStream is) { this.is = is; } @Override public int read() throws IOException { - int ch = is.read(); + int ch = this.is.read(); if (ch != -1) { bos.write(ch); } diff --git a/spring-web/src/main/java/org/springframework/web/filter/ShallowEtagHeaderFilter.java b/spring-web/src/main/java/org/springframework/web/filter/ShallowEtagHeaderFilter.java index 1179f2a8421..cfe71f0a7cf 100644 --- a/spring-web/src/main/java/org/springframework/web/filter/ShallowEtagHeaderFilter.java +++ b/spring-web/src/main/java/org/springframework/web/filter/ShallowEtagHeaderFilter.java @@ -29,8 +29,8 @@ import javax.servlet.http.HttpServletResponseWrapper; import org.springframework.http.HttpMethod; import org.springframework.util.Assert; -import org.springframework.util.ResizableByteArrayOutputStream; import org.springframework.util.DigestUtils; +import org.springframework.util.ResizableByteArrayOutputStream; import org.springframework.util.StreamUtils; import org.springframework.web.util.WebUtils; @@ -175,7 +175,7 @@ public class ShallowEtagHeaderFilter extends OncePerRequestFilter { */ private static class ShallowEtagResponseWrapper extends HttpServletResponseWrapper { - private final ResizableByteArrayOutputStream content = new ResizableByteArrayOutputStream(); + private final ResizableByteArrayOutputStream content = new ResizableByteArrayOutputStream(1024); private final ServletOutputStream outputStream = new ResponseServletOutputStream(); @@ -232,22 +232,22 @@ public class ShallowEtagHeaderFilter extends OncePerRequestFilter { return this.writer; } - @Override - public void resetBuffer() { - this.content.reset(); - } - @Override public void reset() { super.reset(); resetBuffer(); } - private int getStatusCode() { + @Override + public void resetBuffer() { + this.content.reset(); + } + + public int getStatusCode() { return this.statusCode; } - private byte[] toByteArray() { + public byte[] toByteArray() { return this.content.toByteArray(); } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/xml/MarshallingView.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/xml/MarshallingView.java index 5a01641866f..e96d3c9a57d 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/xml/MarshallingView.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/xml/MarshallingView.java @@ -104,7 +104,7 @@ public class MarshallingView extends AbstractView { if (toBeMarshalled == null) { throw new IllegalStateException("Unable to locate object to be marshalled in model: " + model); } - ByteArrayOutputStream bos = new ByteArrayOutputStream(2048); + ByteArrayOutputStream bos = new ByteArrayOutputStream(1024); this.marshaller.marshal(toBeMarshalled, new StreamResult(bos)); setResponseContentType(request, response);