13

I have a jax-rs service which receives a set of parameters in the path, pathparameters. These parameters may be strings containing values not suitable for urls, so they are urlencoded on the client side using the java.net.UrlEncoder like so:

String param = URLEncoder.encode(o.toString(), "UTF-8");

This is used to build the url supplier/group/param1/param2/param3. If one of these are changed due to the urlencoding, for instance if it is only a space, the string received on the service is a + sign.

@GET
@Path("{supplierId}/{groupCode}/{groupId}")
@Produces({MediaType.APPLICATION_XML, MediaType.TEXT_XML})
public SupplierGroup getSupplierGroup(@PathParam("supplierId") BigDecimal supplierId,
        @PathParam("groupCode") String groupCode,
        @PathParam("groupId") BigDecimal groupId) {
    //now groupCode is "+", not " "
}

I would expect jaxrs to automatically decode encoded path params.

EDIT: Testing a bit more I discovered that when sending using %20 for the space, it is able to decode the param.

Runar Halse
  • 3,528
  • 10
  • 39
  • 59
  • Using `URI.toAsciiString` does not always work. The answer from @yegor256 is more robust - add the `@Encoded` annotation above the function decaration – SomethingSomething Dec 12 '17 at 17:03

2 Answers2

15

The automatic encoding of pathparams works as expected. The problem was that %20is used to encode spaces in the url itself, while + is used to encode the query string(the part after the ?). Pathparams are really parts of the URL, so %20 should be used.

Using URI.toAsciiString() instead of UrlEncoder.encode(...) and passing the different parts gives a valid url that is decoded correctly.

Runar Halse
  • 3,528
  • 10
  • 39
  • 59
  • This appears to be correct, although many clients will encode space as "+" in a path :-(. Further reading: https://stackoverflow.com/questions/1634271/url-encoding-the-space-character-or-20 – Rich Feb 04 '19 at 13:48
3

Quote from PathParam javadoc:

The value is URL decoded unless this is disabled using the Encoded annotation.

yegor256
  • 102,010
  • 123
  • 446
  • 597
  • 3
    exactly! But this does not happen, and I have not disabled it! – Runar Halse Nov 30 '12 at 06:10
  • which JAX-RS implementation are you using? – yegor256 Nov 30 '12 at 07:08
  • this is a problem with tests running an embedded openejb container. We are going to deploy this to a websphere server though...is that a cxf implementation? – Runar Halse Nov 30 '12 at 07:36
  • You're experiencing this problem in unit tests or in WebSphere? In unit tests there won't be any URL decoding, since you're calling methods directly, without any JAX-RS servlets – yegor256 Nov 30 '12 at 09:43
  • I'm experiencing this in integration tests, where I run an standalone embedded open ejb container and perform http calls with a client to a service. – Runar Halse Nov 30 '12 at 10:40
  • This is the most helpful answer I came across in a long time. Simply added an `@Encoded` annotation above the function declaration. That was enought for the parameters to stop being decoded to unicode from `%XX` ASCII encoded characters – SomethingSomething Dec 12 '17 at 17:01