Michael Dz
Michael Dz

Reputation: 3834

Webflux Webclient escape slash in URL

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?

Upvotes: 7

Views: 5073

Answers (3)

lanoxx
lanoxx

Reputation: 13051

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);

Upvotes: -1

123
123

Reputation: 11216

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();
    

Upvotes: 7

V. Mokrecov
V. Mokrecov

Reputation: 1094

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())...

Upvotes: 2

Related Questions