Consistent support for Charset/StandardCharsets in UriUtils etc
Issue: SPR-15613
This commit is contained in:
@@ -71,7 +71,7 @@ public class Jaxb2XmlEncoder extends AbstractSingleValueEncoder<Object> {
|
||||
|
||||
@Override
|
||||
protected Flux<DataBuffer> encode(Object value, DataBufferFactory dataBufferFactory,
|
||||
ResolvableType type, MimeType mimeType, @Nullable Map<String, Object> hints) {
|
||||
ResolvableType type, @Nullable MimeType mimeType, @Nullable Map<String, Object> hints) {
|
||||
try {
|
||||
DataBuffer buffer = dataBufferFactory.allocateBuffer(1024);
|
||||
OutputStream outputStream = buffer.asOutputStream();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -66,8 +66,8 @@ public abstract class AbstractWireFeedHttpMessageConverter<T extends WireFeed> e
|
||||
|
||||
WireFeedInput feedInput = new WireFeedInput();
|
||||
MediaType contentType = inputMessage.getHeaders().getContentType();
|
||||
Charset charset =
|
||||
(contentType != null && contentType.getCharset() != null? contentType.getCharset() : DEFAULT_CHARSET);
|
||||
Charset charset = (contentType != null && contentType.getCharset() != null ?
|
||||
contentType.getCharset() : DEFAULT_CHARSET);
|
||||
try {
|
||||
Reader reader = new InputStreamReader(inputMessage.getBody(), charset);
|
||||
return (T) feedInput.build(reader);
|
||||
@@ -81,20 +81,17 @@ public abstract class AbstractWireFeedHttpMessageConverter<T extends WireFeed> e
|
||||
protected void writeInternal(T wireFeed, HttpOutputMessage outputMessage)
|
||||
throws IOException, HttpMessageNotWritableException {
|
||||
|
||||
String wireFeedEncoding = wireFeed.getEncoding();
|
||||
if (!StringUtils.hasLength(wireFeedEncoding)) {
|
||||
wireFeedEncoding = DEFAULT_CHARSET.name();
|
||||
}
|
||||
Charset charset = (StringUtils.hasLength(wireFeed.getEncoding()) ?
|
||||
Charset.forName(wireFeed.getEncoding()) : DEFAULT_CHARSET);
|
||||
MediaType contentType = outputMessage.getHeaders().getContentType();
|
||||
if (contentType != null) {
|
||||
Charset wireFeedCharset = Charset.forName(wireFeedEncoding);
|
||||
contentType = new MediaType(contentType.getType(), contentType.getSubtype(), wireFeedCharset);
|
||||
contentType = new MediaType(contentType.getType(), contentType.getSubtype(), charset);
|
||||
outputMessage.getHeaders().setContentType(contentType);
|
||||
}
|
||||
|
||||
WireFeedOutput feedOutput = new WireFeedOutput();
|
||||
try {
|
||||
Writer writer = new OutputStreamWriter(outputMessage.getBody(), wireFeedEncoding);
|
||||
Writer writer = new OutputStreamWriter(outputMessage.getBody(), charset);
|
||||
feedOutput.output(wireFeed, writer);
|
||||
}
|
||||
catch (FeedException ex) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -18,6 +18,7 @@ package org.springframework.web.client;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.lang.Nullable;
|
||||
@@ -32,7 +33,7 @@ public class RestClientResponseException extends RestClientException {
|
||||
|
||||
private static final long serialVersionUID = -8803556342728481792L;
|
||||
|
||||
private static final String DEFAULT_CHARSET = "ISO-8859-1";
|
||||
private static final Charset DEFAULT_CHARSET = StandardCharsets.ISO_8859_1;
|
||||
|
||||
|
||||
private final int rawStatusCode;
|
||||
@@ -62,7 +63,7 @@ public class RestClientResponseException extends RestClientException {
|
||||
this.statusText = statusText;
|
||||
this.responseHeaders = responseHeaders;
|
||||
this.responseBody = (responseBody != null ? responseBody : new byte[0]);
|
||||
this.responseCharset = (responseCharset != null ? responseCharset.name() : DEFAULT_CHARSET);
|
||||
this.responseCharset = (responseCharset != null ? responseCharset.name() : null);
|
||||
}
|
||||
|
||||
|
||||
@@ -98,6 +99,9 @@ public class RestClientResponseException extends RestClientException {
|
||||
* Return the response body as a string.
|
||||
*/
|
||||
public String getResponseBodyAsString() {
|
||||
if (this.responseCharset == null) {
|
||||
return new String(this.responseBody, DEFAULT_CHARSET);
|
||||
}
|
||||
try {
|
||||
return new String(this.responseBody, this.responseCharset);
|
||||
}
|
||||
|
||||
@@ -57,6 +57,17 @@ public abstract class UriUtils {
|
||||
return HierarchicalUriComponents.encodeUriComponent(scheme, encoding, HierarchicalUriComponents.Type.SCHEME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the given URI scheme with the given encoding.
|
||||
* @param scheme the scheme to be encoded
|
||||
* @param charset the character encoding to encode to
|
||||
* @return the encoded scheme
|
||||
* @since 5.0
|
||||
*/
|
||||
public static String encodeScheme(String scheme, Charset charset) {
|
||||
return HierarchicalUriComponents.encodeUriComponent(scheme, charset, HierarchicalUriComponents.Type.SCHEME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the given URI authority with the given encoding.
|
||||
* @param authority the authority to be encoded
|
||||
@@ -68,6 +79,17 @@ public abstract class UriUtils {
|
||||
return HierarchicalUriComponents.encodeUriComponent(authority, encoding, HierarchicalUriComponents.Type.AUTHORITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the given URI authority with the given encoding.
|
||||
* @param authority the authority to be encoded
|
||||
* @param charset the character encoding to encode to
|
||||
* @return the encoded authority
|
||||
* @since 5.0
|
||||
*/
|
||||
public static String encodeAuthority(String authority, Charset charset) {
|
||||
return HierarchicalUriComponents.encodeUriComponent(authority, charset, HierarchicalUriComponents.Type.AUTHORITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the given URI user info with the given encoding.
|
||||
* @param userInfo the user info to be encoded
|
||||
@@ -79,6 +101,17 @@ public abstract class UriUtils {
|
||||
return HierarchicalUriComponents.encodeUriComponent(userInfo, encoding, HierarchicalUriComponents.Type.USER_INFO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the given URI user info with the given encoding.
|
||||
* @param userInfo the user info to be encoded
|
||||
* @param charset the character encoding to encode to
|
||||
* @return the encoded user info
|
||||
* @since 5.0
|
||||
*/
|
||||
public static String encodeUserInfo(String userInfo, Charset charset) {
|
||||
return HierarchicalUriComponents.encodeUriComponent(userInfo, charset, HierarchicalUriComponents.Type.USER_INFO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the given URI host with the given encoding.
|
||||
* @param host the host to be encoded
|
||||
@@ -90,6 +123,17 @@ public abstract class UriUtils {
|
||||
return HierarchicalUriComponents.encodeUriComponent(host, encoding, HierarchicalUriComponents.Type.HOST_IPV4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the given URI host with the given encoding.
|
||||
* @param host the host to be encoded
|
||||
* @param charset the character encoding to encode to
|
||||
* @return the encoded host
|
||||
* @since 5.0
|
||||
*/
|
||||
public static String encodeHost(String host, Charset charset) {
|
||||
return HierarchicalUriComponents.encodeUriComponent(host, charset, HierarchicalUriComponents.Type.HOST_IPV4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the given URI port with the given encoding.
|
||||
* @param port the port to be encoded
|
||||
@@ -101,6 +145,17 @@ public abstract class UriUtils {
|
||||
return HierarchicalUriComponents.encodeUriComponent(port, encoding, HierarchicalUriComponents.Type.PORT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the given URI port with the given encoding.
|
||||
* @param port the port to be encoded
|
||||
* @param charset the character encoding to encode to
|
||||
* @return the encoded port
|
||||
* @since 5.0
|
||||
*/
|
||||
public static String encodePort(String port, Charset charset) {
|
||||
return HierarchicalUriComponents.encodeUriComponent(port, charset, HierarchicalUriComponents.Type.PORT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the given URI path with the given encoding.
|
||||
* @param path the path to be encoded
|
||||
@@ -112,6 +167,17 @@ public abstract class UriUtils {
|
||||
return HierarchicalUriComponents.encodeUriComponent(path, encoding, HierarchicalUriComponents.Type.PATH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the given URI path with the given encoding.
|
||||
* @param path the path to be encoded
|
||||
* @param charset the character encoding to encode to
|
||||
* @return the encoded path
|
||||
* @since 5.0
|
||||
*/
|
||||
public static String encodePath(String path, Charset charset) {
|
||||
return HierarchicalUriComponents.encodeUriComponent(path, charset, HierarchicalUriComponents.Type.PATH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the given URI path segment with the given encoding.
|
||||
* @param segment the segment to be encoded
|
||||
@@ -123,6 +189,17 @@ public abstract class UriUtils {
|
||||
return HierarchicalUriComponents.encodeUriComponent(segment, encoding, HierarchicalUriComponents.Type.PATH_SEGMENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the given URI path segment with the given encoding.
|
||||
* @param segment the segment to be encoded
|
||||
* @param charset the character encoding to encode to
|
||||
* @return the encoded segment
|
||||
* @since 5.0
|
||||
*/
|
||||
public static String encodePathSegment(String segment, Charset charset) {
|
||||
return HierarchicalUriComponents.encodeUriComponent(segment, charset, HierarchicalUriComponents.Type.PATH_SEGMENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the given URI query with the given encoding.
|
||||
* @param query the query to be encoded
|
||||
@@ -134,6 +211,17 @@ public abstract class UriUtils {
|
||||
return HierarchicalUriComponents.encodeUriComponent(query, encoding, HierarchicalUriComponents.Type.QUERY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the given URI query with the given encoding.
|
||||
* @param query the query to be encoded
|
||||
* @param charset the character encoding to encode to
|
||||
* @return the encoded query
|
||||
* @since 5.0
|
||||
*/
|
||||
public static String encodeQuery(String query, Charset charset) {
|
||||
return HierarchicalUriComponents.encodeUriComponent(query, charset, HierarchicalUriComponents.Type.QUERY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the given URI query parameter with the given encoding.
|
||||
* @param queryParam the query parameter to be encoded
|
||||
@@ -145,6 +233,17 @@ public abstract class UriUtils {
|
||||
return HierarchicalUriComponents.encodeUriComponent(queryParam, encoding, HierarchicalUriComponents.Type.QUERY_PARAM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the given URI query parameter with the given encoding.
|
||||
* @param queryParam the query parameter to be encoded
|
||||
* @param charset the character encoding to encode to
|
||||
* @return the encoded query parameter
|
||||
* @since 5.0
|
||||
*/
|
||||
public static String encodeQueryParam(String queryParam, Charset charset) {
|
||||
return HierarchicalUriComponents.encodeUriComponent(queryParam, charset, HierarchicalUriComponents.Type.QUERY_PARAM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the given URI fragment with the given encoding.
|
||||
* @param fragment the fragment to be encoded
|
||||
@@ -156,6 +255,18 @@ public abstract class UriUtils {
|
||||
return HierarchicalUriComponents.encodeUriComponent(fragment, encoding, HierarchicalUriComponents.Type.FRAGMENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the given URI fragment with the given encoding.
|
||||
* @param fragment the fragment to be encoded
|
||||
* @param charset the character encoding to encode to
|
||||
* @return the encoded fragment
|
||||
* @since 5.0
|
||||
*/
|
||||
public static String encodeFragment(String fragment, Charset charset) {
|
||||
return HierarchicalUriComponents.encodeUriComponent(fragment, charset, HierarchicalUriComponents.Type.FRAGMENT);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Encode characters outside the unreserved character set as defined in
|
||||
* <a href="https://tools.ietf.org/html/rfc3986#section-2">RFC 3986 Section 2</a>.
|
||||
@@ -179,49 +290,18 @@ public abstract class UriUtils {
|
||||
* @param source the String to be encoded
|
||||
* @param charset the character encoding to encode to
|
||||
* @return the encoded String
|
||||
* @since 5.0
|
||||
*/
|
||||
public static String encode(String source, Charset charset) {
|
||||
HierarchicalUriComponents.Type type = HierarchicalUriComponents.Type.URI;
|
||||
return HierarchicalUriComponents.encodeUriComponent(source, charset, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply {@link #encode(String, String)} to the values in the given URI
|
||||
* variables and return a new Map containing the encoded values.
|
||||
* @param uriVariables the URI variable values to be encoded
|
||||
* @return the encoded String
|
||||
* @since 5.0
|
||||
*/
|
||||
public static Map<String, String> encodeUriVariables(Map<String, ?> uriVariables) {
|
||||
Map<String, String> result = new LinkedHashMap<>(uriVariables.size());
|
||||
uriVariables.forEach((key, value) -> {
|
||||
String stringValue = (value != null ? value.toString() : "");
|
||||
result.put(key, encode(stringValue, StandardCharsets.UTF_8));
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply {@link #encode(String, String)} to the values in the given URI
|
||||
* variables and return a new array containing the encoded values.
|
||||
* @param uriVariables the URI variable values to be encoded
|
||||
* @return the encoded String
|
||||
* @since 5.0
|
||||
*/
|
||||
public static Object[] encodeUriVariables(Object... uriVariables) {
|
||||
return Arrays.stream(uriVariables)
|
||||
.map(value -> {
|
||||
String stringValue = (value != null ? value.toString() : "");
|
||||
return encode(stringValue, StandardCharsets.UTF_8);
|
||||
})
|
||||
.collect(Collectors.toList()).toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode the given encoded URI component.
|
||||
* <p>See {@link StringUtils#uriDecode(String, Charset)} for the decoding rules.
|
||||
* @param source the encoded String
|
||||
* @param encoding the encoding
|
||||
* @param encoding the character encoding to use
|
||||
* @return the decoded value
|
||||
* @throws IllegalArgumentException when the given source contains invalid encoded sequences
|
||||
* @throws UnsupportedEncodingException when the given encoding parameter is not supported
|
||||
@@ -232,6 +312,21 @@ public abstract class UriUtils {
|
||||
return StringUtils.uriDecode(source, Charset.forName(encoding));
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode the given encoded URI component.
|
||||
* <p>See {@link StringUtils#uriDecode(String, Charset)} for the decoding rules.
|
||||
* @param source the encoded String
|
||||
* @param charset the character encoding to use
|
||||
* @return the decoded value
|
||||
* @throws IllegalArgumentException when the given source contains invalid encoded sequences
|
||||
* @since 5.0
|
||||
* @see StringUtils#uriDecode(String, Charset)
|
||||
* @see java.net.URLDecoder#decode(String, String)
|
||||
*/
|
||||
public static String decode(String source, Charset charset) {
|
||||
return StringUtils.uriDecode(source, charset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the file extension from the given URI path.
|
||||
* @param path the URI path (e.g. "/products/index.html")
|
||||
@@ -257,4 +352,37 @@ public abstract class UriUtils {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Apply {@link #encode(String, String)} to the values in the given URI
|
||||
* variables and return a new Map containing the encoded values.
|
||||
* @param uriVariables the URI variable values to be encoded
|
||||
* @return the encoded String
|
||||
* @since 5.0
|
||||
*/
|
||||
static Map<String, String> encodeUriVariables(Map<String, ?> uriVariables) {
|
||||
Map<String, String> result = new LinkedHashMap<>(uriVariables.size());
|
||||
uriVariables.forEach((key, value) -> {
|
||||
String stringValue = (value != null ? value.toString() : "");
|
||||
result.put(key, encode(stringValue, StandardCharsets.UTF_8));
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply {@link #encode(String, String)} to the values in the given URI
|
||||
* variables and return a new array containing the encoded values.
|
||||
* @param uriVariables the URI variable values to be encoded
|
||||
* @return the encoded String
|
||||
* @since 5.0
|
||||
*/
|
||||
static Object[] encodeUriVariables(Object... uriVariables) {
|
||||
return Arrays.stream(uriVariables)
|
||||
.map(value -> {
|
||||
String stringValue = (value != null ? value.toString() : "");
|
||||
return encode(stringValue, StandardCharsets.UTF_8);
|
||||
})
|
||||
.collect(Collectors.toList()).toArray();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.web.util.pattern;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -84,12 +83,7 @@ class CaptureVariablePathElement extends PathElement {
|
||||
// TODO possible optimization - only regex match if rest of pattern matches? Benefit likely to vary pattern to pattern
|
||||
if (includesPercent(matchingContext.candidate, candidateIndex, nextPos)) {
|
||||
substringForDecoding = new String(matchingContext.candidate, candidateIndex, nextPos);
|
||||
try {
|
||||
candidateCapture = UriUtils.decode(substringForDecoding,StandardCharsets.UTF_8.name());
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
candidateCapture = UriUtils.decode(substringForDecoding, StandardCharsets.UTF_8);
|
||||
}
|
||||
else {
|
||||
candidateCapture = new SubSequence(matchingContext.candidate, candidateIndex, nextPos);
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.web.util.pattern;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -311,15 +310,9 @@ class InternalPathPatternParser {
|
||||
private char[] getPathElementText(boolean encodeElement) {
|
||||
char[] pathElementText = new char[this.pos - this.pathElementStart];
|
||||
if (encodeElement) {
|
||||
try {
|
||||
String unencoded = new String(this.pathPatternData, this.pathElementStart, this.pos - this.pathElementStart);
|
||||
String encoded = UriUtils.encodeFragment(unencoded, StandardCharsets.UTF_8.name());
|
||||
pathElementText = encoded.toCharArray();
|
||||
}
|
||||
catch (UnsupportedEncodingException ex) {
|
||||
// Should never happen...
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
String unencoded = new String(this.pathPatternData, this.pathElementStart, this.pos - this.pathElementStart);
|
||||
String encoded = UriUtils.encodeFragment(unencoded, StandardCharsets.UTF_8);
|
||||
pathElementText = encoded.toCharArray();
|
||||
}
|
||||
else {
|
||||
System.arraycopy(this.pathPatternData, this.pathElementStart, pathElementText, 0,
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.web.util.pattern;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.springframework.web.util.UriUtils;
|
||||
@@ -105,23 +104,18 @@ abstract class PathElement {
|
||||
/**
|
||||
* Decode an input CharSequence if necessary.
|
||||
* @param toDecode the input char sequence that should be decoded if necessary
|
||||
* @returns the decoded result
|
||||
* @return the decoded result
|
||||
*/
|
||||
protected String decode(CharSequence toDecode) {
|
||||
CharSequence decoded = toDecode;
|
||||
if (includesPercent(toDecode)) {
|
||||
try {
|
||||
decoded = UriUtils.decode(toDecode.toString(), StandardCharsets.UTF_8.name());
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
decoded = UriUtils.decode(toDecode.toString(), StandardCharsets.UTF_8);
|
||||
}
|
||||
return decoded.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param char sequence of characters
|
||||
* @param chars sequence of characters
|
||||
* @param from start position (included in check)
|
||||
* @param to end position (excluded from check)
|
||||
* @return true if the chars array includes a '%' character between the specified positions
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.web.util.pattern;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
@@ -132,13 +131,8 @@ class RegexPathElement extends PathElement {
|
||||
return "";
|
||||
}
|
||||
String substring = s.substring(start, end);
|
||||
try {
|
||||
String encodedSubString = UriUtils.encodePath(substring, StandardCharsets.UTF_8.name());
|
||||
encodedRegexBuilder.append(encodedSubString);
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
String encodedSubString = UriUtils.encodePath(substring, StandardCharsets.UTF_8);
|
||||
encodedRegexBuilder.append(encodedSubString);
|
||||
return Pattern.quote(substring);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user