Search code examples
javajava-8requestjerseyurlencode

How can I avoid escaping a WebTarget query parameter?


I want to turn off URL encoding for Jersey requests, or for certain parameters.

The server I'm talking to requires the format of example.com/path?query=foo:bar

With Jackson WebTarget,

final WebTarget target = ClientBuilder.newClient()
    .target(url)
    .queryParam("query", "{queryVal}")
    .resolveTemplate("queryVal", "foo:bar");

Sadly this produces example.com/path?query=foo bar which is not accepted by the server.

I've searched a lot for this and the only promising avenue seems to be something to do with javax.ws.rs.core.Configuration, but I haven't gotten far with that yet.


Solution

  • I figured it out: The solution is to use a request filter as documented in Advanced Features of the Client API

    final WebTarget target = ClientBuilder.newClient()
        .target(url)
        .queryParam("query", "{queryVal}")
        .resolveTemplate("queryVal", "foo:bar")
        .register(Filter.class)
    

    and then we have

    @Provider
    public class Filter implements ClientRequestFilter {
        private static final Logger logger = LoggerFactory.getLogger(Filter.class);
    
        @Override
        public void filter(ClientRequestContext ctx) throws IOException {
            try {
                logger.debug("Before: {}", ctx.getUri());
                //this is gonna get ugly
                ctx.setUri(new URI(
                    URLDecoder.decode(ctx.getUri().toString(), StandardCharsets.UTF_8.toString())));
                logger.debug("After: {}", ctx.getUri());
            } catch (URISyntaxException e) {
                e.printStackTrace();
            }
        }
    }
    

    Output:

    com.example.client.Filter : Before: http://example.com/path?query=foo%3Abar
    com.example.client.Filter : After: http://example.com/path?query=foo:bar