Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tomcat, JAX-RS, Jersey, @PathParam: how to pass dots and slashes?

Having a method like this:

@GET @Path("/name/{name}")
@Produces(MediaType.TEXT_PLAIN)
public String getProperty(@PathParam("name") String name) {
        System.out.println(name);
}

How do I pass a value like "test./test"?

/name/test./test     gives HTTP 404
/name/test.%2Ftest   gives HTTP 400
/name/test.%252Ftest prints test%2Ftest

But if I do name = URLDecoder.decode(name); it prints /test and the first part of test. disappears.

There is one or two questions like this already but they are old and there was no good solution found, I thought I'll ask again.

like image 273
Maxim Suponya Avatar asked Jun 21 '12 02:06

Maxim Suponya


2 Answers

The pattern in the @Path annotation is internally turned into a regular expression, with the template parts matching only selected characters by default. In particular, they normally don't match / characters; that's almost always the right thing to do (as it lets you put templates part way through a path) but in this case it isn't as you're wanting to consume the whole subsequent path. To get everything, we have to override the regular expression fragment for that particular template; this is actually pretty easy, since we just put in the template fragment a : followed by the RE that we want to use:

@GET @Produces(MediaType.TEXT_PLAIN)
@Path("/name/{name:.+}")
public String getProperty(@PathParam("name") String name) {
    return name;
}

This will match all characters after the /name/ (up to but not including any ? query part) but will only match if there's something there at all. Be aware that if you have any other @Path("/name/...") things about, things can get really confusing! So don't do that.

like image 169
Donal Fellows Avatar answered Sep 24 '22 14:09

Donal Fellows


If you using tomcat, and want pass / in pathparam. besides the @Path("/name/{name:.+}") stuff as 'Donal Fellows' said, you should add -Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true to your jvm arguments, see also tomcat security-howto.

like image 28
turtledove Avatar answered Sep 23 '22 14:09

turtledove