Affects: \
Please see a demo .
public static void main(String args[]){
DefaultUriBuilderFactory uriBuilderFactory = new DefaultUriBuilderFactory();
uriBuilderFactory.setEncodingMode(EncodingMode.NONE);
WebClient webClient = WebClient.builder().uriBuilderFactory(uriBuilderFactory)
.baseUrl("http://localhots:9090").build();
webClient.get().uri("/api/v1/query").retrieve().bodyToMono(String.class).block();
}
Maybe you already know what I mean. I want a webClient implementation that does not perform url encoding and decoding and has a baseurl. But unfortunately my code above seems to be able to meet my needs, but in fact baseurl does not take effect. I looked through the source code,the root cause is found in the following code.
private UriBuilderFactory initUriBuilderFactory() {
if (this.uriBuilderFactory != null) {
return this.uriBuilderFactory;
}
DefaultUriBuilderFactory factory = this.baseUrl != null ?
new DefaultUriBuilderFactory(this.baseUrl) : new DefaultUriBuilderFactory();
factory.setDefaultUriVariables(this.defaultUriVariables);
return factory;
}
If uriBuilderFactory is set, baseurl will be ignored.I looked at the specific implementation of DefaultUriBuilderFactory again,At this point I understand that the correct way should be to set the baseurl through the constructor of DefaultUriBuilderFactory.
I think this kind of API design that If uriBuilderFactory is set, baseurl will be ignored will cause some confusion.I wonder if you think so.Is it possible to eliminate this confusion by improving the DefaultUriBuilderFactory and related code.
Thank you for reading and sincerely look forward to your reply.
Comment From: rstoyanchev
They are mutually exclusive options. It's in the Javadoc for Builder#uriBuilderFactory:
* This is an alternative to and effectively overrides the following:
* <ul>
* <li>{@link #baseUrl(String)}
* <li>{@link #defaultUriVariables(Map)}.
* </ul>
The Javadoc on baseUrl and defaultUriVariables could be improved to mention they are nothing but shortcuts for passing in a UriBuilderFactory but you can't use both at the same time.
Comment From: chenqimiao
@rstoyanchev Thank you for your reply.
Yes, the documentation can state this.
But I wonder if there are better technical means to optimize this operation.
I originally wanted to improve the initUriBuilderFactory method. By creating a DefaultUriBuilderFactory instance, I copied the attributes of uriBuilderFactory and baseUrl to it , if baseUrl of the uriBuilderFactory is null and uriBuilderFactory is an instance of DefaultUriBuilderFactory. But the baseUrl of the uriBuilderFactory is strongly dependent and is final.
Comment From: rstoyanchev
The documentation already stated this, so it is by design. Please have another look at the Javadoc now. It should be much less ambiguous.
Generally I can see how this could be surprising, but keep in mind that uriBuilderFactory accepts a more general contract UriBuilderFactory, and it might not always be possible to implement baseUrl as a delegate method, which could lead to surprises of its own.
In the end it is simpler to treat those as nothing but shortcuts and otherwise mutually exclusive. Use them if that's all you need to change, or take more control by preparing your own DefaultUriBuilderFactory.
Comment From: chenqimiao
@rstoyanchev Thank you very much, it is much clearer now. A typo in the document and I fix in #24613