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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With