diff --git a/spring-core/src/main/java/org/springframework/core/codec/ResourceEncoder.java b/spring-core/src/main/java/org/springframework/core/codec/ResourceEncoder.java index 03305a85c8c..07a16af9533 100644 --- a/spring-core/src/main/java/org/springframework/core/codec/ResourceEncoder.java +++ b/spring-core/src/main/java/org/springframework/core/codec/ResourceEncoder.java @@ -68,7 +68,7 @@ public class ResourceEncoder extends AbstractSingleValueEncoder { @Override protected Flux encode(Resource resource, DataBufferFactory dataBufferFactory, - ResolvableType type, MimeType mimeType, @Nullable Map hints) { + ResolvableType type, @Nullable MimeType mimeType, @Nullable Map hints) { try { if (resource.isFile()) { diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/DefaultLobHandler.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/DefaultLobHandler.java index 1aed1412226..21e5aee67cb 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/DefaultLobHandler.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/DefaultLobHandler.java @@ -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. @@ -21,7 +21,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.io.StringReader; -import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.sql.Blob; import java.sql.Clob; import java.sql.PreparedStatement; @@ -322,17 +322,12 @@ public class DefaultLobHandler extends AbstractLobHandler { if (streamAsLob) { if (asciiStream != null) { - try { - Reader reader = new InputStreamReader(asciiStream, "US-ASCII"); - if (contentLength >= 0) { - ps.setClob(paramIndex, reader, contentLength); - } - else { - ps.setClob(paramIndex, reader); - } + Reader reader = new InputStreamReader(asciiStream, StandardCharsets.US_ASCII); + if (contentLength >= 0) { + ps.setClob(paramIndex, reader, contentLength); } - catch (UnsupportedEncodingException ex) { - throw new SQLException("US-ASCII encoding not supported: " + ex); + else { + ps.setClob(paramIndex, reader); } } else { diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/PassThroughClob.java b/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/PassThroughClob.java index e29551b3556..882085c946f 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/PassThroughClob.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/support/lob/PassThroughClob.java @@ -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. @@ -23,7 +23,6 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.io.Reader; import java.io.StringReader; -import java.io.UnsupportedEncodingException; import java.io.Writer; import java.nio.charset.StandardCharsets; import java.sql.Clob; @@ -72,19 +71,14 @@ class PassThroughClob implements Clob { @Override public Reader getCharacterStream() throws SQLException { - try { - if (this.content != null) { - return new StringReader(this.content); - } - else if (this.characterStream != null) { - return this.characterStream; - } - else { - return new InputStreamReader(this.asciiStream, "US-ASCII"); - } + if (this.content != null) { + return new StringReader(this.content); } - catch (UnsupportedEncodingException ex) { - throw new SQLException("US-ASCII encoding not supported: " + ex); + else if (this.characterStream != null) { + return this.characterStream; + } + else { + return new InputStreamReader(this.asciiStream, StandardCharsets.US_ASCII); } } @@ -102,9 +96,6 @@ class PassThroughClob implements Clob { return this.asciiStream; } } - catch (UnsupportedEncodingException ex) { - throw new SQLException("US-ASCII encoding not supported: " + ex); - } catch (IOException ex) { throw new SQLException("Failed to read stream content: " + ex); } diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java index 5405bfe5815..21271275380 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java @@ -19,7 +19,6 @@ package org.springframework.test.web.servlet.request; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; -import java.io.UnsupportedEncodingException; import java.net.URI; import java.nio.charset.StandardCharsets; import java.security.Principal; @@ -698,17 +697,12 @@ public class MockHttpServletRequestBuilder } private void addRequestParams(MockHttpServletRequest request, MultiValueMap map) { - try { - for (Entry> entry : map.entrySet()) { - for (String value : entry.getValue()) { - value = (value != null) ? UriUtils.decode(value, "UTF-8") : null; - request.addParameter(UriUtils.decode(entry.getKey(), "UTF-8"), value); - } + for (Entry> entry : map.entrySet()) { + for (String value : entry.getValue()) { + value = (value != null ? UriUtils.decode(value, StandardCharsets.UTF_8) : null); + request.addParameter(UriUtils.decode(entry.getKey(), StandardCharsets.UTF_8), value); } } - catch (UnsupportedEncodingException ex) { - // shouldn't happen - } } private MultiValueMap parseFormData(final MediaType mediaType) { diff --git a/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlEncoder.java b/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlEncoder.java index ea143d565e4..e9867ee3e5b 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlEncoder.java +++ b/spring-web/src/main/java/org/springframework/http/codec/xml/Jaxb2XmlEncoder.java @@ -71,7 +71,7 @@ public class Jaxb2XmlEncoder extends AbstractSingleValueEncoder { @Override protected Flux encode(Object value, DataBufferFactory dataBufferFactory, - ResolvableType type, MimeType mimeType, @Nullable Map hints) { + ResolvableType type, @Nullable MimeType mimeType, @Nullable Map hints) { try { DataBuffer buffer = dataBufferFactory.allocateBuffer(1024); OutputStream outputStream = buffer.asOutputStream(); diff --git a/spring-web/src/main/java/org/springframework/http/converter/feed/AbstractWireFeedHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/feed/AbstractWireFeedHttpMessageConverter.java index 79f1a635a25..2a6426524af 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/feed/AbstractWireFeedHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/feed/AbstractWireFeedHttpMessageConverter.java @@ -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 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 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) { diff --git a/spring-web/src/main/java/org/springframework/web/client/RestClientResponseException.java b/spring-web/src/main/java/org/springframework/web/client/RestClientResponseException.java index 3779143280b..f0eba4d5613 100644 --- a/spring-web/src/main/java/org/springframework/web/client/RestClientResponseException.java +++ b/spring-web/src/main/java/org/springframework/web/client/RestClientResponseException.java @@ -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); } diff --git a/spring-web/src/main/java/org/springframework/web/util/UriUtils.java b/spring-web/src/main/java/org/springframework/web/util/UriUtils.java index 244af0d448f..0f9082abe21 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UriUtils.java +++ b/spring-web/src/main/java/org/springframework/web/util/UriUtils.java @@ -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 * RFC 3986 Section 2. @@ -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 encodeUriVariables(Map uriVariables) { - Map 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. *

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. + *

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 encodeUriVariables(Map uriVariables) { + Map 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(); + } + } diff --git a/spring-web/src/main/java/org/springframework/web/util/pattern/CaptureVariablePathElement.java b/spring-web/src/main/java/org/springframework/web/util/pattern/CaptureVariablePathElement.java index 090bbc06a04..c439d1fd9d5 100644 --- a/spring-web/src/main/java/org/springframework/web/util/pattern/CaptureVariablePathElement.java +++ b/spring-web/src/main/java/org/springframework/web/util/pattern/CaptureVariablePathElement.java @@ -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); diff --git a/spring-web/src/main/java/org/springframework/web/util/pattern/InternalPathPatternParser.java b/spring-web/src/main/java/org/springframework/web/util/pattern/InternalPathPatternParser.java index 6a5c19ee7c4..3081de80d5b 100644 --- a/spring-web/src/main/java/org/springframework/web/util/pattern/InternalPathPatternParser.java +++ b/spring-web/src/main/java/org/springframework/web/util/pattern/InternalPathPatternParser.java @@ -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, diff --git a/spring-web/src/main/java/org/springframework/web/util/pattern/PathElement.java b/spring-web/src/main/java/org/springframework/web/util/pattern/PathElement.java index 55bf05caee7..dc65ce74782 100644 --- a/spring-web/src/main/java/org/springframework/web/util/pattern/PathElement.java +++ b/spring-web/src/main/java/org/springframework/web/util/pattern/PathElement.java @@ -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 diff --git a/spring-web/src/main/java/org/springframework/web/util/pattern/RegexPathElement.java b/spring-web/src/main/java/org/springframework/web/util/pattern/RegexPathElement.java index 603ef663f20..d588801a685 100644 --- a/spring-web/src/main/java/org/springframework/web/util/pattern/RegexPathElement.java +++ b/spring-web/src/main/java/org/springframework/web/util/pattern/RegexPathElement.java @@ -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); } diff --git a/spring-web/src/test/java/org/springframework/web/util/UriUtilsTests.java b/spring-web/src/test/java/org/springframework/web/util/UriUtilsTests.java index 2227674abc9..7f067ef9a68 100644 --- a/spring-web/src/test/java/org/springframework/web/util/UriUtilsTests.java +++ b/spring-web/src/test/java/org/springframework/web/util/UriUtilsTests.java @@ -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. @@ -17,6 +17,8 @@ package org.springframework.web.util; import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import org.junit.Test; @@ -28,81 +30,81 @@ import static org.junit.Assert.*; */ public class UriUtilsTests { - private static final String ENC = "UTF-8"; + private static final Charset CHARSET = StandardCharsets.UTF_8; @Test public void encodeScheme() throws UnsupportedEncodingException { - assertEquals("Invalid encoded result", "foobar+-.", UriUtils.encodeScheme("foobar+-.", ENC)); - assertEquals("Invalid encoded result", "foo%20bar", UriUtils.encodeScheme("foo bar", ENC)); + assertEquals("Invalid encoded result", "foobar+-.", UriUtils.encodeScheme("foobar+-.", CHARSET)); + assertEquals("Invalid encoded result", "foo%20bar", UriUtils.encodeScheme("foo bar", CHARSET)); } @Test public void encodeUserInfo() throws UnsupportedEncodingException { - assertEquals("Invalid encoded result", "foobar:", UriUtils.encodeUserInfo("foobar:", ENC)); - assertEquals("Invalid encoded result", "foo%20bar", UriUtils.encodeUserInfo("foo bar", ENC)); + assertEquals("Invalid encoded result", "foobar:", UriUtils.encodeUserInfo("foobar:", CHARSET)); + assertEquals("Invalid encoded result", "foo%20bar", UriUtils.encodeUserInfo("foo bar", CHARSET)); } @Test public void encodeHost() throws UnsupportedEncodingException { - assertEquals("Invalid encoded result", "foobar", UriUtils.encodeHost("foobar", ENC)); - assertEquals("Invalid encoded result", "foo%20bar", UriUtils.encodeHost("foo bar", ENC)); + assertEquals("Invalid encoded result", "foobar", UriUtils.encodeHost("foobar", CHARSET)); + assertEquals("Invalid encoded result", "foo%20bar", UriUtils.encodeHost("foo bar", CHARSET)); } @Test public void encodePort() throws UnsupportedEncodingException { - assertEquals("Invalid encoded result", "80", UriUtils.encodePort("80", ENC)); + assertEquals("Invalid encoded result", "80", UriUtils.encodePort("80", CHARSET)); } @Test public void encodePath() throws UnsupportedEncodingException { - assertEquals("Invalid encoded result", "/foo/bar", UriUtils.encodePath("/foo/bar", ENC)); - assertEquals("Invalid encoded result", "/foo%20bar", UriUtils.encodePath("/foo bar", ENC)); - assertEquals("Invalid encoded result", "/Z%C3%BCrich", UriUtils.encodePath("/Z\u00fcrich", ENC)); + assertEquals("Invalid encoded result", "/foo/bar", UriUtils.encodePath("/foo/bar", CHARSET)); + assertEquals("Invalid encoded result", "/foo%20bar", UriUtils.encodePath("/foo bar", CHARSET)); + assertEquals("Invalid encoded result", "/Z%C3%BCrich", UriUtils.encodePath("/Z\u00fcrich", CHARSET)); } @Test public void encodePathSegment() throws UnsupportedEncodingException { - assertEquals("Invalid encoded result", "foobar", UriUtils.encodePathSegment("foobar", ENC)); - assertEquals("Invalid encoded result", "%2Ffoo%2Fbar", UriUtils.encodePathSegment("/foo/bar", ENC)); + assertEquals("Invalid encoded result", "foobar", UriUtils.encodePathSegment("foobar", CHARSET)); + assertEquals("Invalid encoded result", "%2Ffoo%2Fbar", UriUtils.encodePathSegment("/foo/bar", CHARSET)); } @Test public void encodeQuery() throws UnsupportedEncodingException { - assertEquals("Invalid encoded result", "foobar", UriUtils.encodeQuery("foobar", ENC)); - assertEquals("Invalid encoded result", "foo%20bar", UriUtils.encodeQuery("foo bar", ENC)); - assertEquals("Invalid encoded result", "foobar/+", UriUtils.encodeQuery("foobar/+", ENC)); - assertEquals("Invalid encoded result", "T%C5%8Dky%C5%8D", UriUtils.encodeQuery("T\u014dky\u014d", ENC)); + assertEquals("Invalid encoded result", "foobar", UriUtils.encodeQuery("foobar", CHARSET)); + assertEquals("Invalid encoded result", "foo%20bar", UriUtils.encodeQuery("foo bar", CHARSET)); + assertEquals("Invalid encoded result", "foobar/+", UriUtils.encodeQuery("foobar/+", CHARSET)); + assertEquals("Invalid encoded result", "T%C5%8Dky%C5%8D", UriUtils.encodeQuery("T\u014dky\u014d", CHARSET)); } @Test public void encodeQueryParam() throws UnsupportedEncodingException { - assertEquals("Invalid encoded result", "foobar", UriUtils.encodeQueryParam("foobar", ENC)); - assertEquals("Invalid encoded result", "foo%20bar", UriUtils.encodeQueryParam("foo bar", ENC)); - assertEquals("Invalid encoded result", "foo%26bar", UriUtils.encodeQueryParam("foo&bar", ENC)); + assertEquals("Invalid encoded result", "foobar", UriUtils.encodeQueryParam("foobar", CHARSET)); + assertEquals("Invalid encoded result", "foo%20bar", UriUtils.encodeQueryParam("foo bar", CHARSET)); + assertEquals("Invalid encoded result", "foo%26bar", UriUtils.encodeQueryParam("foo&bar", CHARSET)); } @Test public void encodeFragment() throws UnsupportedEncodingException { - assertEquals("Invalid encoded result", "foobar", UriUtils.encodeFragment("foobar", ENC)); - assertEquals("Invalid encoded result", "foo%20bar", UriUtils.encodeFragment("foo bar", ENC)); - assertEquals("Invalid encoded result", "foobar/", UriUtils.encodeFragment("foobar/", ENC)); + assertEquals("Invalid encoded result", "foobar", UriUtils.encodeFragment("foobar", CHARSET)); + assertEquals("Invalid encoded result", "foo%20bar", UriUtils.encodeFragment("foo bar", CHARSET)); + assertEquals("Invalid encoded result", "foobar/", UriUtils.encodeFragment("foobar/", CHARSET)); } @Test public void decode() throws UnsupportedEncodingException { - assertEquals("Invalid encoded URI", "", UriUtils.decode("", ENC)); - assertEquals("Invalid encoded URI", "foobar", UriUtils.decode("foobar", ENC)); - assertEquals("Invalid encoded URI", "foo bar", UriUtils.decode("foo%20bar", ENC)); - assertEquals("Invalid encoded URI", "foo+bar", UriUtils.decode("foo%2bbar", ENC)); - assertEquals("Invalid encoded result", "T\u014dky\u014d", UriUtils.decode("T%C5%8Dky%C5%8D", ENC)); - assertEquals("Invalid encoded result", "/Z\u00fcrich", UriUtils.decode("/Z%C3%BCrich", ENC)); - assertEquals("Invalid encoded result", "T\u014dky\u014d", UriUtils.decode("T\u014dky\u014d", ENC)); + assertEquals("Invalid encoded URI", "", UriUtils.decode("", CHARSET)); + assertEquals("Invalid encoded URI", "foobar", UriUtils.decode("foobar", CHARSET)); + assertEquals("Invalid encoded URI", "foo bar", UriUtils.decode("foo%20bar", CHARSET)); + assertEquals("Invalid encoded URI", "foo+bar", UriUtils.decode("foo%2bbar", CHARSET)); + assertEquals("Invalid encoded result", "T\u014dky\u014d", UriUtils.decode("T%C5%8Dky%C5%8D", CHARSET)); + assertEquals("Invalid encoded result", "/Z\u00fcrich", UriUtils.decode("/Z%C3%BCrich", CHARSET)); + assertEquals("Invalid encoded result", "T\u014dky\u014d", UriUtils.decode("T\u014dky\u014d", CHARSET)); } @Test(expected = IllegalArgumentException.class) public void decodeInvalidSequence() throws UnsupportedEncodingException { - UriUtils.decode("foo%2", ENC); + UriUtils.decode("foo%2", CHARSET); } @Test diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RedirectView.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RedirectView.java index 592ca19d127..55a037006e3 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RedirectView.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/RedirectView.java @@ -16,7 +16,6 @@ package org.springframework.web.reactive.result.view; -import java.io.UnsupportedEncodingException; import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.Collections; @@ -260,14 +259,8 @@ public class RedirectView extends AbstractUrlBasedView { } private String encodeUriVariable(String text) { - try { - // Strict encoding of all reserved URI characters - return UriUtils.encode(text, StandardCharsets.UTF_8.name()); - } - catch (UnsupportedEncodingException ex) { - // Should never happen... - throw new IllegalStateException(ex); - } + // Strict encoding of all reserved URI characters + return UriUtils.encode(text, StandardCharsets.UTF_8); } /** diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/AbstractHttpSendingTransportHandler.java b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/AbstractHttpSendingTransportHandler.java index 7b99092e2ce..15737932b15 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/AbstractHttpSendingTransportHandler.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/sockjs/transport/handler/AbstractHttpSendingTransportHandler.java @@ -17,7 +17,7 @@ package org.springframework.web.socket.sockjs.transport.handler; import java.io.IOException; -import java.io.UnsupportedEncodingException; +import java.nio.charset.StandardCharsets; import java.util.regex.Pattern; import org.springframework.http.MediaType; @@ -121,14 +121,8 @@ public abstract class AbstractHttpSendingTransportHandler extends AbstractTransp if (StringUtils.isEmpty(value)) { return null; } - try { - String result = UriUtils.decode(value, "UTF-8"); - return (CALLBACK_PARAM_PATTERN.matcher(result).matches() ? result : null); - } - catch (UnsupportedEncodingException ex) { - // should never happen - throw new SockJsException("Unable to decode callback query parameter", null, ex); - } + String result = UriUtils.decode(value, StandardCharsets.UTF_8); + return (CALLBACK_PARAM_PATTERN.matcher(result).matches() ? result : null); } }