Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Encoded slash (%2F) with Spring RequestMapping path param gives HTTP 400

This is not a duplicate referenced question, because it is Spring specific. Whoever added that (3 years after the fact!) didn't bother to read the question or comment thread to see what the real answer was. The accepted answer isn't quite the answer, but the author of the answer never came back and edited it like I asked.

Given the restful method below, Spring 3.1 gives a 400 error with "The request sent by the client was syntactically incorrect ()." when the token parameter contains a URL encoded slash (%2F), for example "https://somewhere.com/ws/stuff/lookup/resourceId/287559/token/R4o6lI%2FbBx43/userName/jim" Without the %2F everything works fine. A 3rd party is already calling this service (of course!) so I can't change what they send, in the short term at least. Any ideas on how to work around this on the server side?

This problem is described very well here https://jira.springsource.org/browse/SPR-8662 though that issue is related to UriTemplate which I am not using that I can tell.

@RequestMapping("/ws/stuff/**") @Controller public class StuffController {   @RequestMapping(value = "/ws/stuff/lookup/resourceId/{resourceId}/token/{token}/userName/{userName}", method = RequestMethod.GET)    public @ResponseBody    String provisionResource(@PathVariable("resourceId") String resourceId, @PathVariable("token") String token, @PathVariable("userName") String userName, ModelMap modelMap,          HttpServletRequest request, HttpServletResponse response) {       return handle(resourceId, userName, request, token, modelMap);    } } 

Note: This is on Glassfish 3.1.2, and at first it was Grizzly/Glassfish not accepting the slash, but

-Dcom.sun.grizzly.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true

fixed that.

asadmin set configs.config.server-config.network-config.protocols.protocol.http-listener-2.http.encoded-slash-enabled=true

didn't seem to help.

like image 672
Jim Avatar asked Nov 20 '12 20:11

Jim


People also ask

What is difference between @PathParam and @PathVariable?

@PathParam: it is used to inject the value of named URI path parameters that were defined in @Path expression. @Pathvariable: This annotation is used to handle template variables in the request URI mapping ,and used them as method parameters.

What is @PathVariable annotation in spring boot?

Simply put, the @PathVariable annotation can be used to handle template variables in the request URI mapping, and set them as method parameters.

Is PathVariable required by default?

From Spring 4.3. 3 version, @PathVariable annotation has required attribute, to specify it is mandatorily required in URI. The default value for this attribute is true if we make this attribute value to false, then Spring MVC will not throw an exception.


2 Answers

for spring-boot, the following did the trick

@SpringBootApplication public class Application extends WebMvcConfigurerAdapter {      public static void main(String[] args) throws Exception {         System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");         SpringApplication.run(Application.class, args);     }      @Override     public void configurePathMatch(PathMatchConfigurer configurer) {         UrlPathHelper urlPathHelper = new UrlPathHelper();         urlPathHelper.setUrlDecode(false);         configurer.setUrlPathHelper(urlPathHelper);     }  } 
like image 98
iamiddy Avatar answered Nov 12 '22 13:11

iamiddy


This could be your answer: urlencoded Forward slash is breaking URL

I would suggest not putting that in the path, move it to a request param instead.

Work around:

You could change the RequestMapping to

@RequestMapping(value = "/ws/stuff/lookup/resourceId/**", method = RequestMethod.GET)  

and then parse the path variables manually from the request object.

like image 36
Solubris Avatar answered Nov 12 '22 15:11

Solubris