7

I need to include a slash in an URL to access RabbitMQ API and I'm trying to fetch data using WebClient:

WebClient.builder()
     .baseUrl("https://RABBIT_HOSTNAME/api/queues/%2F/QUEUE_NAME")
     .build()
     .get().exchange();

When I replace / with %2F I can see in the request descriptor that %2F has been changed to %252F and because of it I'm getting not found response.

I've tried the following options:

"\\/" - WebClient changes to %5C but Rabbit doesn't interpret it correctly and returns 404.

"%5C" - WebClient changes to %255C, Rabbit returns 404.

How can I persist %2F in an url using WebClient?

Michael Dz
  • 3,655
  • 8
  • 40
  • 74

3 Answers3

7

By default it will always encode the URL, so I can see two options

  1. Completely ignore the baseUrl method and pass a fully qualified URL into the uri method which will override the baseUrl method.

    WebClient.builder()
         .build()
         .uri(URI.create( "https://RABBIT_HOSTNAME/api/queues/%2F/QUEUE_NAME"))
         .get().exchange();
    
  2. Create your own custom UriBuilderFactory, map a Uri, and set the encoding to NONE

    public class CustomUriBuilderFactory extends DefaultUriBuilderFactory {
    
        public CustomUriBuilderFactory(String baseUriTemplate) {
            super(UriComponentsBuilder.fromHttpUrl(baseUriTemplate));
            super.setEncodingMode(EncodingMode.NONE);
        }
    }
    

    and then you can use uriBuilderFactory of baseUrl, which will allow you to still use uri for just the uri part

    WebClient.builder()
            .uriBuilderFactory(
                new CustomUriBuilderFactory(
                    "https://RABBIT_HOSTNAME/api/queues/%2F/QUEUE_NAME"
            ))
            .build()
            .get()
            .uri(whatever)
            .exchange();
    
123
  • 10,778
  • 2
  • 22
  • 45
2

You can implement this:

URI uri = URI.create("%2F");

And:

WebClient.builder()
        .baseUrl("https://RABBIT_HOSTNAME/api/queues")
        .build()
        .post()
        .uri(uriBuilder -> uriBuilder.pathSegment(uri.getPath(), "QUEUE_NAME").build())...
V. Mokrecov
  • 1,014
  • 1
  • 11
  • 20
0

If you use the uriBuilder and specify a path with a placeholder that is completed via the build method then the argument in the build method is automatically encoded correctly:

client.get()
      .uri(uriBuilder -> uriBuilder.path("/foo/{fooValue}")
                                   .build(valueWithSpecialCharacter))
      .retrieve()
      .bodyToMono(Foo.class);
lanoxx
  • 12,249
  • 13
  • 87
  • 142