In a test, I am injecting an example URL with a colon for a port number ("http://example.com:port") into my configuration, which is then used by my production code to construct a UriComponentsBuilder
which ultimately creates a URI String.
However, that colon character is being converted into a forward slash by the UriComponentsBuilder
, as demonstrated in this MCVE:
@Test
public void portNumberFromHttpUrl() {
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("http://example.com:port");
String uriString = builder.toUriString();
assertThat(uriString).isEqualTo("http://example.com:port");
}
This test fails as follows:
org.junit.ComparisonFailure:
Expected :"http://example.com:port"
Actual :"http://example.com/port"
Why is the :
being converted to a /
?
The MCVE helped me answer this myself almost immediately, but I'll leave the question here because I couldn't find the same question here or anywhere else online, and I guess it might save someone else some time:
It seems that UriComponentsBuilder
recognises that a port should be a number, so this (more realistic) case passes:
@Test
public void portNumberFromHttpUrl() {
UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("http://example.com:123");
String uriString = builder.toUriString();
assertThat(uriString).isEqualTo("http://example.com:123");
}
From a little more investigation it seems that it puts a /
before the first non-numeric character that it encounters after a :
, so:
http://example.com:a123
-> http://example.com/a123
http://example.com:12a3
-> http://example.com:12/a3
http://example.com:123a
-> http://example.com:123/a
Not immediately obvious, but makes sense, I guess.