I have a ConfigurationProperties
class containing a property of type java.net.URI
.
If I configure a value of file:///C:/some/path/with/#/in/it
it (correctly) gets converted to a URI with a fragment component (which is not what I need in this case).
However, if I configure the value as a correctly encoded URI like this file:///C:/some/path/with/%23/in/it
, it (incorrectly) gets converted to this URI: file:///C:/some/path/with/%2523/in/it
.
I don't see a way to configure this URI so it gets bound correctly.
The reason for this is that the org.springframework.beans.propertyeditors.URIEditor
tries to guess which part of the URI is correctly encoded and which isn't which is a task that's impossible to do correctly for all cases.
This has been improved upon several times in #10673, #21123, and #11743, but I think the approach is fundamentally flawed and the URIEditor
should just not try to fix incorrectly encoded URIs by default.
The best workaround I could find was to use URLs instead of URIs.
Comment From: rstoyanchev
To handle an encoded URI, the encode
property should be off. This works:
String s = "file:///C:/some/path/with/%23/in/it";
URI uri = new URIEditor(false).createURI(s);
assertThat(uri.toString()).isEqualTo(s);
Comment From: AdrianDiemerDev
Yes, I know about the constructor but that doesn't help with the ConfigurationProperties binding because the binding uses a hard coded instance of URIEditor with encode = false
. I couldn't find any way to replace that instance.
But even if it is somehow possible to replace it there, I don't think interpreting RFC3986 compliant URIs erroneously should be the default. I get that the idea is to make it more tolerant to wrongly encoded URIs but I don't think that should go at the expense of supporting correct URIs.
Though, I have no idea how to change this without introducing a breaking change...
Comment From: rstoyanchev
There is no way to change this without breaking someone else. Compatibility aside, what change did you actually have in mind?
Comment From: AdrianDiemerDev
Well, as mentioned before, in a perfect world, I feel like a standard conform URI should always be interpreted correctly by default.
But since that would be breaking, I guess the next best option would be to allow overriding the URIEditor instance when instantiating a new org.springframework.boot.context.properties.bind.Binder
as well as for the default Binder.
I don't really have a sufficient understanding of the classes involved here to outline a proposed change.
Comment From: rstoyanchev
Have you tried something like the below?
@Bean
static CustomEditorConfigurer customEditorConfigurer() {
CustomEditorConfigurer configurer = new CustomEditorConfigurer();
configurer.setPropertyEditorRegistrars(new PropertyEditorRegistrar[] {
registry -> registry.registerCustomEditor(URI.class, new URIEditor(false))
});
return configurer;
}
As far as I can tell, Binder
uses BindConverter
, which is customized through a Consumer<PropertyEditorRegistry>
that's configured to copy from the BeanFactory.
Comment From: spring-projects-issues
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.
Comment From: spring-projects-issues
Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.