Skip to content

Commit 12d4dc1

Browse files
committed
Polishing external contribution
This commit makes several changes to PR #24651. - Add byte[] getContentAsByteArray() on Resource. - Remove getContentAsString() from Resource, as it relied on the default charset which is not reliable. - Add getContentAsString() to EncodedResource, as a charset is provided through the constructor. See gh-24651
1 parent 4da2499 commit 12d4dc1

File tree

12 files changed

+192
-124
lines changed

12 files changed

+192
-124
lines changed

spring-core/src/main/java/org/springframework/core/io/AbstractFileResolvingResource.java

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,7 @@
2626
import java.net.URLConnection;
2727
import java.nio.channels.FileChannel;
2828
import java.nio.channels.ReadableByteChannel;
29-
import java.nio.charset.Charset;
30-
import java.nio.file.Files;
3129
import java.nio.file.NoSuchFileException;
32-
import java.nio.file.Paths;
3330
import java.nio.file.StandardOpenOption;
3431
import java.util.jar.JarEntry;
3532

@@ -323,39 +320,6 @@ protected void customizeConnection(URLConnection con) throws IOException {
323320
protected void customizeConnection(HttpURLConnection con) throws IOException {
324321
}
325322

326-
/**
327-
* This implementation returns the contents of a file as a string using the
328-
* system default Charset. Provided the resource exists and the context has
329-
* access to it, the contents will be returned as a single string with line
330-
* feed characters retained.
331-
* @return the contents of the requested file as a {@code String}.
332-
* @throws FileNotFoundException in the event the file path is invalid.
333-
* @throws IOException if the file can not be read or cannot be serialzied.
334-
*/
335-
@Override
336-
public String getContentAsString() throws IOException {
337-
338-
if( !exists() ) {
339-
throw new FileNotFoundException(getDescription() + " cannot be found.");
340-
}
341-
if ( !isReadable() ) {
342-
throw new IOException(getDescription() + " cannot be opened for reading.");
343-
}
344-
return new String(Files.readAllBytes(Paths.get(getFile().getAbsolutePath())), Charset.defaultCharset());
345-
}
346-
347-
@Override
348-
public String getContentAsString(Charset charset) throws IOException {
349-
350-
if( !exists() ) {
351-
throw new FileNotFoundException(getDescription() + " cannot be found.");
352-
}
353-
if ( !isReadable() ) {
354-
throw new IOException(getDescription() + " cannot be opened for reading.");
355-
}
356-
return new String(Files.readAllBytes(Paths.get(getFile().getAbsolutePath())), charset);
357-
358-
}
359323

360324
/**
361325
* Inner delegate class, avoiding a hard JBoss VFS API dependency at runtime.

spring-core/src/main/java/org/springframework/core/io/ByteArrayResource.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2023 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.
@@ -19,6 +19,7 @@
1919
import java.io.ByteArrayInputStream;
2020
import java.io.IOException;
2121
import java.io.InputStream;
22+
import java.nio.charset.Charset;
2223
import java.util.Arrays;
2324

2425
import org.springframework.lang.Nullable;
@@ -100,6 +101,19 @@ public InputStream getInputStream() throws IOException {
100101
return new ByteArrayInputStream(this.byteArray);
101102
}
102103

104+
@Override
105+
public byte[] getContentAsByteArray() throws IOException {
106+
int length = this.byteArray.length;
107+
byte[] result = new byte[length];
108+
System.arraycopy(this.byteArray, 0, result, 0, length);
109+
return result;
110+
}
111+
112+
@Override
113+
public String getContentAsString(Charset charset) throws IOException {
114+
return new String(this.byteArray, charset);
115+
}
116+
103117
/**
104118
* This implementation returns a description that includes the passed-in
105119
* {@code description}, if any.

spring-core/src/main/java/org/springframework/core/io/FileSystemResource.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2023 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.
@@ -27,6 +27,7 @@
2727
import java.nio.channels.FileChannel;
2828
import java.nio.channels.ReadableByteChannel;
2929
import java.nio.channels.WritableByteChannel;
30+
import java.nio.charset.Charset;
3031
import java.nio.file.FileSystem;
3132
import java.nio.file.Files;
3233
import java.nio.file.NoSuchFileException;
@@ -196,6 +197,26 @@ public InputStream getInputStream() throws IOException {
196197
}
197198
}
198199

200+
@Override
201+
public byte[] getContentAsByteArray() throws IOException {
202+
try {
203+
return Files.readAllBytes(this.filePath);
204+
}
205+
catch (NoSuchFileException ex) {
206+
throw new FileNotFoundException(ex.getMessage());
207+
}
208+
}
209+
210+
@Override
211+
public String getContentAsString(Charset charset) throws IOException {
212+
try {
213+
return Files.readString(this.filePath, charset);
214+
}
215+
catch (NoSuchFileException ex) {
216+
throw new FileNotFoundException(ex.getMessage());
217+
}
218+
}
219+
199220
/**
200221
* This implementation checks whether the underlying file is marked as writable
201222
* (and corresponds to an actual file with content, not to a directory).

spring-core/src/main/java/org/springframework/core/io/PathResource.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2023 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.
@@ -25,6 +25,7 @@
2525
import java.net.URL;
2626
import java.nio.channels.ReadableByteChannel;
2727
import java.nio.channels.WritableByteChannel;
28+
import java.nio.charset.Charset;
2829
import java.nio.file.Files;
2930
import java.nio.file.NoSuchFileException;
3031
import java.nio.file.OpenOption;
@@ -141,6 +142,26 @@ public InputStream getInputStream() throws IOException {
141142
return Files.newInputStream(this.path);
142143
}
143144

145+
@Override
146+
public byte[] getContentAsByteArray() throws IOException {
147+
try {
148+
return Files.readAllBytes(this.path);
149+
}
150+
catch (NoSuchFileException ex) {
151+
throw new FileNotFoundException(ex.getMessage());
152+
}
153+
}
154+
155+
@Override
156+
public String getContentAsString(Charset charset) throws IOException {
157+
try {
158+
return Files.readString(this.path, charset);
159+
}
160+
catch (NoSuchFileException ex) {
161+
throw new FileNotFoundException(ex.getMessage());
162+
}
163+
}
164+
144165
/**
145166
* This implementation checks whether the underlying file is marked as writable
146167
* (and corresponds to an actual file with content, not to a directory).

spring-core/src/main/java/org/springframework/core/io/Resource.java

Lines changed: 21 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2023 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.
@@ -17,16 +17,17 @@
1717
package org.springframework.core.io;
1818

1919
import java.io.File;
20-
import java.io.FileNotFoundException;
2120
import java.io.IOException;
2221
import java.io.InputStream;
22+
import java.io.InputStreamReader;
2323
import java.net.URI;
2424
import java.net.URL;
2525
import java.nio.channels.Channels;
2626
import java.nio.channels.ReadableByteChannel;
2727
import java.nio.charset.Charset;
2828

2929
import org.springframework.lang.Nullable;
30+
import org.springframework.util.FileCopyUtils;
3031

3132
/**
3233
* Interface for a resource descriptor that abstracts from the actual
@@ -179,40 +180,29 @@ default ReadableByteChannel readableChannel() throws IOException {
179180
String getDescription();
180181

181182
/**
182-
* Return a {@link ReadableByteChannel}.
183-
* <p>It is expected that each call creates a <i>fresh</i> channel.
184-
* <p>The default implementation returns {@link Channels#newChannel(InputStream)}
185-
* with the result of {@link #getInputStream()}.
186-
* @return the byte channel for the underlying resource (must not be {@code null})
187-
* @throws java.io.FileNotFoundException if the underlying resource doesn't exist
188-
* @throws IOException if the content channel could not be opened
189-
* @since 5.0
190-
* @see #getInputStream()
191-
*/
192-
193-
/**
194-
* Returns the contents of a file as a string using the system default Charset.
195-
* <p>The default implementation returns a {@link Object#toString()} representation of the resource.
196-
* @return the contents of the requested file as a {@code String}.
197-
* @throws FileNotFoundException in the event the file path is invalid.
198-
* @throws IOException if the file can not be read or cannot be accessed.
199-
* @since 5.2.5
183+
* Return the contents of this resource as a byte array.
184+
* @return the contents of this resource as byte array
185+
* @throws java.io.FileNotFoundException if the resource cannot be resolved as
186+
* absolute file path, i.e. if the resource is not available in a file system
187+
* @throws IOException in case of general resolution/reading failures
188+
* @since 6.0.5
200189
*/
201-
default String getContentAsString() throws IOException{
202-
return toString();
190+
default byte[] getContentAsByteArray() throws IOException {
191+
return FileCopyUtils.copyToByteArray(getInputStream());
203192
}
204193

205194
/**
206-
* Returns the contents of a file as a string using the specified Charset.
207-
* <p>The default implementation returns a {@link Object#toString()} representation of the resource.
208-
* @param charset the {@code Charset} to use to deserialize the content. Defaults to system default.
209-
* @return the contents of the requested file as a {@code String}.
210-
* @throws FileNotFoundException in the event the file path is invalid.
211-
* @throws IOException if the file can not be read or cannot be accessed.
212-
* @since 5.2.5
195+
* Returns the contents of this resource as a string, using the specified
196+
* charset.
197+
* @param charset the charset to use for decoding
198+
* @return the contents of this resource as a {@code String}
199+
* @throws java.io.FileNotFoundException if the resource cannot be resolved as
200+
* absolute file path, i.e. if the resource is not available in a file system
201+
* @throws IOException in case of general resolution/reading failures
202+
* @since 6.0.5
213203
*/
214-
default String getContentAsString(Charset charset) throws IOException{
215-
return toString();
204+
default String getContentAsString(Charset charset) throws IOException {
205+
return FileCopyUtils.copyToString(new InputStreamReader(getInputStream(), charset));
216206
}
217207

218208
}

spring-core/src/main/java/org/springframework/core/io/support/EncodedResource.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2023 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.
@@ -159,6 +159,27 @@ public InputStream getInputStream() throws IOException {
159159
return this.resource.getInputStream();
160160
}
161161

162+
/**
163+
* Returns the contents of the specified resource as a string, using the specified
164+
* {@link #getCharset() Charset} or {@linkplain #getEncoding() encoding}
165+
* (if any).
166+
* @throws IOException if opening the resource failed
167+
* @since 6.0.5
168+
*/
169+
public String getContentAsString() throws IOException {
170+
Charset charset;
171+
if (this.charset != null) {
172+
charset = this.charset;
173+
}
174+
else if (this.encoding != null) {
175+
charset = Charset.forName(this.encoding);
176+
}
177+
else {
178+
charset = Charset.defaultCharset();
179+
}
180+
return this.resource.getContentAsString(charset);
181+
}
182+
162183

163184
@Override
164185
public boolean equals(@Nullable Object other) {

0 commit comments

Comments
 (0)