Browse Source

Improve usage of ByteArrayOutputStream/ByteArrayInputStream

Closes gh-24805
pull/24818/head
Сергей Цыпанов 6 years ago committed by Sam Brannen
parent
commit
e63d1cf12d
  1. 22
      spring-context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCache.java
  2. 19
      spring-core/src/main/java/org/springframework/util/StreamUtils.java
  3. 2
      spring-core/src/main/java/org/springframework/util/StringUtils.java
  4. 3
      spring-core/src/testFixtures/java/org/springframework/core/testfixture/io/SerializationTestUtils.java
  5. 5
      spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompDecoder.java
  6. 6
      spring-test/src/main/java/org/springframework/mock/http/MockHttpOutputMessage.java
  7. 5
      spring-web/src/main/java/org/springframework/http/ContentDisposition.java
  8. 3
      spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java
  9. 8
      spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/JettyXhrTransport.java
  10. 14
      spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/UndertowXhrTransport.java

22
spring-context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCache.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 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.
@ -202,15 +202,10 @@ public class ConcurrentMapCache extends AbstractValueAdaptingCache { @@ -202,15 +202,10 @@ public class ConcurrentMapCache extends AbstractValueAdaptingCache {
}
}
private Object serializeValue(SerializationDelegate serialization, Object storeValue) throws IOException {
private static Object serializeValue(SerializationDelegate serialization, Object storeValue) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
serialization.serialize(storeValue, out);
return out.toByteArray();
}
finally {
out.close();
}
serialization.serialize(storeValue, out);
return out.toByteArray();
}
@Override
@ -229,14 +224,9 @@ public class ConcurrentMapCache extends AbstractValueAdaptingCache { @@ -229,14 +224,9 @@ public class ConcurrentMapCache extends AbstractValueAdaptingCache {
}
private Object deserializeValue(SerializationDelegate serialization, Object storeValue) throws IOException {
private static Object deserializeValue(SerializationDelegate serialization, Object storeValue) throws IOException {
ByteArrayInputStream in = new ByteArrayInputStream((byte[]) storeValue);
try {
return serialization.deserialize(in);
}
finally {
in.close();
}
return serialization.deserialize(in);
}
}

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

@ -25,6 +25,7 @@ import java.io.InputStream; @@ -25,6 +25,7 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.nio.charset.Charset;
@ -238,6 +239,24 @@ public abstract class StreamUtils { @@ -238,6 +239,24 @@ public abstract class StreamUtils {
return new NonClosingOutputStream(out);
}
/**
* More effective equivalent of {@code new String(baos.toByteArray(), charset)}
* As far as at invocation point {@code charset} is already available,
* no exception is expected to be thrown.
*
* @param baos {@link ByteArrayOutputStream} to be flushed into String
* @param charset applicable {@link Charset}
* @return String represenation of bytes stored in {@code baos}
*/
public static String baosToString(ByteArrayOutputStream baos, Charset charset) {
Assert.notNull(baos, "No ByteArrayOutputStream specified");
Assert.notNull(charset, "No Charset specified");
try {
return baos.toString(charset.name());
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
private static class NonClosingInputStream extends FilterInputStream {

2
spring-core/src/main/java/org/springframework/util/StringUtils.java

@ -774,7 +774,7 @@ public abstract class StringUtils { @@ -774,7 +774,7 @@ public abstract class StringUtils {
bos.write(ch);
}
}
return (changed ? new String(bos.toByteArray(), charset) : source);
return changed ? StreamUtils.baosToString(bos, charset) : source;
}
/**

3
spring-core/src/testFixtures/java/org/springframework/core/testfixture/io/SerializationTestUtils.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 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.
@ -55,7 +55,6 @@ public class SerializationTestUtils { @@ -55,7 +55,6 @@ public class SerializationTestUtils {
oos.writeObject(o);
oos.flush();
}
baos.flush();
byte[] bytes = baos.toByteArray();
ByteArrayInputStream is = new ByteArrayInputStream(bytes);

5
spring-messaging/src/main/java/org/springframework/messaging/simp/stomp/StompDecoder.java

@ -33,6 +33,7 @@ import org.springframework.messaging.support.MessageHeaderInitializer; @@ -33,6 +33,7 @@ import org.springframework.messaging.support.MessageHeaderInitializer;
import org.springframework.messaging.support.NativeMessageHeaderAccessor;
import org.springframework.util.InvalidMimeTypeException;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StreamUtils;
/**
* Decodes one or more STOMP frames contained in a {@link ByteBuffer}.
@ -216,7 +217,7 @@ public class StompDecoder { @@ -216,7 +217,7 @@ public class StompDecoder {
while (byteBuffer.remaining() > 0 && !tryConsumeEndOfLine(byteBuffer)) {
command.write(byteBuffer.get());
}
return new String(command.toByteArray(), StandardCharsets.UTF_8);
return StreamUtils.baosToString(command, StandardCharsets.UTF_8);
}
private void readHeaders(ByteBuffer byteBuffer, StompHeaderAccessor headerAccessor) {
@ -231,7 +232,7 @@ public class StompDecoder { @@ -231,7 +232,7 @@ public class StompDecoder {
headerStream.write(byteBuffer.get());
}
if (headerStream.size() > 0 && headerComplete) {
String header = new String(headerStream.toByteArray(), StandardCharsets.UTF_8);
String header = StreamUtils.baosToString(headerStream, StandardCharsets.UTF_8);
int colonIndex = header.indexOf(':');
if (colonIndex <= 0) {
if (byteBuffer.remaining() > 0) {

6
spring-test/src/main/java/org/springframework/mock/http/MockHttpOutputMessage.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2020 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.
@ -24,6 +24,7 @@ import java.nio.charset.StandardCharsets; @@ -24,6 +24,7 @@ import java.nio.charset.StandardCharsets;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpOutputMessage;
import org.springframework.util.StreamUtils;
/**
* Mock implementation of {@link HttpOutputMessage}.
@ -75,8 +76,7 @@ public class MockHttpOutputMessage implements HttpOutputMessage { @@ -75,8 +76,7 @@ public class MockHttpOutputMessage implements HttpOutputMessage {
* @param charset the charset to use to turn the body content to a String
*/
public String getBodyAsString(Charset charset) {
byte[] bytes = getBodyAsBytes();
return new String(bytes, charset);
return StreamUtils.baosToString(this.body, charset);
}
}

5
spring-web/src/main/java/org/springframework/http/ContentDisposition.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2020 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,6 +27,7 @@ import java.util.List; @@ -27,6 +27,7 @@ import java.util.List;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StreamUtils;
import static java.nio.charset.StandardCharsets.ISO_8859_1;
import static java.nio.charset.StandardCharsets.UTF_8;
@ -419,7 +420,7 @@ public final class ContentDisposition { @@ -419,7 +420,7 @@ public final class ContentDisposition {
throw new IllegalArgumentException(INVALID_HEADER_FIELD_PARAMETER_FORMAT);
}
}
return new String(bos.toByteArray(), charset);
return StreamUtils.baosToString(bos, charset);
}
private static boolean isRFC5987AttrChar(byte c) {

3
spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java

@ -36,6 +36,7 @@ import org.springframework.util.CollectionUtils; @@ -36,6 +36,7 @@ import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;
/**
@ -359,7 +360,7 @@ final class HierarchicalUriComponents extends UriComponents { @@ -359,7 +360,7 @@ final class HierarchicalUriComponents extends UriComponents {
bos.write(hex2);
}
}
return new String(bos.toByteArray(), charset);
return StreamUtils.baosToString(bos, charset);
}
private Type getHostType() {

8
spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/JettyXhrTransport.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2020 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.
@ -35,6 +35,7 @@ import org.springframework.http.HttpStatus; @@ -35,6 +35,7 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StreamUtils;
import org.springframework.util.concurrent.SettableListenableFuture;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.socket.CloseStatus;
@ -247,14 +248,13 @@ public class JettyXhrTransport extends AbstractXhrTransport implements Lifecycle @@ -247,14 +248,13 @@ public class JettyXhrTransport extends AbstractXhrTransport implements Lifecycle
}
private void handleFrame() {
byte[] bytes = this.outputStream.toByteArray();
String content = StreamUtils.baosToString(this.outputStream, SockJsFrame.CHARSET);
this.outputStream.reset();
String content = new String(bytes, SockJsFrame.CHARSET);
if (logger.isTraceEnabled()) {
logger.trace("XHR content received: " + content);
}
if (!PRELUDE.equals(content)) {
this.sockJsSession.handleFrame(new String(bytes, SockJsFrame.CHARSET));
this.sockJsSession.handleFrame(content);
}
}

14
spring-websocket/src/main/java/org/springframework/web/socket/sockjs/client/UndertowXhrTransport.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2020 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.
@ -38,6 +38,7 @@ import io.undertow.util.HeaderMap; @@ -38,6 +38,7 @@ import io.undertow.util.HeaderMap;
import io.undertow.util.HttpString;
import io.undertow.util.Methods;
import io.undertow.util.StringReadChannelListener;
import org.springframework.util.StreamUtils;
import org.xnio.ChannelListener;
import org.xnio.ChannelListeners;
import org.xnio.IoUtils;
@ -405,8 +406,7 @@ public class UndertowXhrTransport extends AbstractXhrTransport { @@ -405,8 +406,7 @@ public class UndertowXhrTransport extends AbstractXhrTransport {
throw new SockJsException("Session closed.", this.session.getId(), null);
}
PooledByteBuffer pooled = bufferPool.allocate();
try {
try (PooledByteBuffer pooled = bufferPool.allocate()) {
int r;
do {
ByteBuffer buffer = pooled.getBuffer();
@ -436,20 +436,16 @@ public class UndertowXhrTransport extends AbstractXhrTransport { @@ -436,20 +436,16 @@ public class UndertowXhrTransport extends AbstractXhrTransport {
catch (IOException exc) {
onFailure(exc);
}
finally {
pooled.close();
}
}
private void handleFrame() {
byte[] bytes = this.outputStream.toByteArray();
String content = StreamUtils.baosToString(this.outputStream, SockJsFrame.CHARSET);
this.outputStream.reset();
String content = new String(bytes, SockJsFrame.CHARSET);
if (logger.isTraceEnabled()) {
logger.trace("XHR content received: " + content);
}
if (!PRELUDE.equals(content)) {
this.session.handleFrame(new String(bytes, SockJsFrame.CHARSET));
this.session.handleFrame(content);
}
}

Loading…
Cancel
Save