Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 342
Michael Dz Avatar asked Apr 17 '20 12:04

Michael Dz


People also ask

What is spring webflux webclient?

The Spring WebFlux WebClient interface enables you to handle web requests from service to service. But you're going to need to take extra steps if you want detailed logging.

What is webflux and how does it work?

WebFlux uses a new router functions feature to apply functional programming to the web layer and bypass declarative controllers and RequestMappings. WebFlux requires you to import Reactor as a core dependency.

What is the difference between webflux client and server?

The client has a functional, fluent API with reactive types for declarative composition, see webflux-reactive-libraries. WebFlux client and server rely on the same non-blocking codecs to encode and decode request and response content.

What port does Spring Boot use for webflux?

Since our Spring Boot project has a dependency declaration for Spring WebFlux, our application will start using the default port of 8080. As the Reactive Web Service is running on port 8080, so I will change the port for our example in this tutorial using port 8081.


2 Answers

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();
    
like image 71
123 Avatar answered Sep 20 '22 02:09

123


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())...
like image 45
V. Mokrecov Avatar answered Sep 18 '22 02:09

V. Mokrecov