diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/propertyeditors/URIEditor.java b/org.springframework.beans/src/main/java/org/springframework/beans/propertyeditors/URIEditor.java index 61731b0b031..01f3849ff29 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/propertyeditors/URIEditor.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/propertyeditors/URIEditor.java @@ -34,6 +34,10 @@ import org.springframework.util.StringUtils; * ("file:", "http:", etc) and Spring's special "classpath:" pseudo-URL, * which will be resolved to a corresponding URI. * + *

By default, this editor will encode Strings into URIs. For instance, + * a space will be encoded into {@code %20}. This behavior can be changed + * by setting calling the {@link #URIEditor(boolean)} constructor. + * *

Note: A URI is more relaxed than a URL in that it does not require * a valid protocol to be specified. Any scheme within a valid URI syntax * is allowed, even without a matching protocol handler being registered. @@ -47,15 +51,31 @@ public class URIEditor extends PropertyEditorSupport { private final ClassLoader classLoader; + private final boolean encode; + + /** - * Create a new URIEditor, converting "classpath:" locations into + * Create a new, encoding URIEditor, converting "classpath:" locations into * standard URIs (not trying to resolve them into physical resources). */ public URIEditor() { this.classLoader = null; + this.encode = true; } + /** + * Create a new URIEditor, converting "classpath:" locations into + * standard URIs (not trying to resolve them into physical resources). + * + * @param encode indicates whether Strings will be encoded or not + */ + public URIEditor(boolean encode) { + this.classLoader = null; + this.encode = encode; + } + + /** * Create a new URIEditor, using the given ClassLoader to resolve * "classpath:" locations into physical resource URLs. @@ -64,6 +84,19 @@ public class URIEditor extends PropertyEditorSupport { */ public URIEditor(ClassLoader classLoader) { this.classLoader = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader()); + this.encode = true; + } + + /** + * Create a new URIEditor, using the given ClassLoader to resolve + * "classpath:" locations into physical resource URLs. + * @param classLoader the ClassLoader to use for resolving "classpath:" locations + * (may be null to indicate the default ClassLoader) + * @param encode indicates whether Strings will be encoded or not + */ + public URIEditor(ClassLoader classLoader, boolean encode) { + this.classLoader = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader()); + this.encode = encode; } @@ -109,13 +142,13 @@ public class URIEditor extends PropertyEditorSupport { */ protected URI createURI(String value) throws URISyntaxException { int idx = value.indexOf(':'); - if (idx != -1) { + if (encode && idx != -1) { String scheme = value.substring(0, idx); String ssp = value.substring(idx + 1); return new URI(scheme, ssp, null); } else { - // value contains no scheme, fallback to default + // not encoding or the value contains no scheme , fallback to default return new URI(value); } } diff --git a/org.springframework.beans/src/test/java/org/springframework/beans/propertyeditors/URIEditorTests.java b/org.springframework.beans/src/test/java/org/springframework/beans/propertyeditors/URIEditorTests.java index 4aeaf87871e..b0437fa03b0 100644 --- a/org.springframework.beans/src/test/java/org/springframework/beans/propertyeditors/URIEditorTests.java +++ b/org.springframework.beans/src/test/java/org/springframework/beans/propertyeditors/URIEditorTests.java @@ -130,4 +130,15 @@ public class URIEditorTests { assertEquals("http://example.com/spaces%20and%20%E2%82%AC", uri.toASCIIString()); } + @Test + public void encodeAlreadyEncodedURI() throws Exception { + PropertyEditor uriEditor = new URIEditor(false); + uriEditor.setAsText("http://example.com/spaces%20and%20%E2%82%AC"); + Object value = uriEditor.getValue(); + assertTrue(value instanceof URI); + URI uri = (URI) value; + assertEquals(uri.toString(), uriEditor.getAsText()); + assertEquals("http://example.com/spaces%20and%20%E2%82%AC", uri.toASCIIString()); + } + }