Search code examples
spring-web

Spring's URIComponentsBuilder converts colon (:) for port number into slash (/)


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 /?


Solution

  • 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.