Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@PathVariable in SpringBoot with slashes in URL

Tags:

I have to get params from URL using @PathValiable in SpringBoot application. These params often have slashes. I don't have a control about what a user would enter in URL so I would like to get what he has entered and then I can handle with it.

I have already looked through materials and answers here, I don't think that for me the good solution is to ask users somehow encode the entering params.

The SpringBoot code is simple:

@RequestMapping("/modules/{moduleName}")
@ResponseBody
public String moduleStrings (@PathVariable("moduleName") String moduleName) throws Exception {

  ...

}

So the URL for example would be the following:

http://localhost:3000/modules/...

The issue is that the param moduleName often has slashes. For example,

metadata-api\cb-metadata-services OR
app-customization-service-impl\\modules\\expand-link-schemes\\common\\app-customization-service-api

So a user definetely can enter:

http://localhost:3000/modules/metadata-api\cb-metadata-services

Is this possible to get everything what a user has entered in URL after /modules/?

If anyone tell me what are the good ways to handle such issue.

like image 608
Kirill Ch Avatar asked Apr 18 '17 11:04

Kirill Ch


People also ask

How do you handle a slash in a URL?

For every case besides the trailing slash directly after the root domain, a trailing slash will be treated as a separate URL.

Can path variable contain slash?

Unfortunately, we soon find out that this returns a 404 if the PathVariable contains a slash. The slash character is the URI standard path delimiter, and all that goes after it counts as a new level in the path hierarchy. As expected, Spring follows this standard.

How do I bypass slash in REST URL?

So if you have slashes in your title you need to find a way to encode and decode your title in the URL if your application cannot make the routing to the resource if the title contains a slash. You could e.g. replace slahes with double hyphens (--) or similar.

What is @PathVariable annotation in Spring boot?

The @PathVariable annotation is used to extract the value of the template variables and assign their value to a method variable. A Spring controller method to process above example is shown below; @RequestMapping("/users/{userid}", method=RequestMethod.


2 Answers

Basing on P.J.Meisch's answer I have come to the simple solution for my case. Also it allows to take into account several slashes in the URL param. It doesn't allow to work with backslashes as in the previous answer too.

@RequestMapping(value = "/modules/**", method = RequestMethod.GET)
@ResponseBody
public String moduleStrings(HttpServletRequest request) {

    String requestURL = request.getRequestURL().toString();

    String moduleName = requestURL.split("/modules/")[1];

    return "module name is: " + moduleName;

}
like image 168
Kirill Ch Avatar answered Sep 21 '22 04:09

Kirill Ch


This code gets the complete path:

@RequestMapping(value = "/modules/{moduleBaseName}/**", method = RequestMethod.GET)
@ResponseBody
public String moduleStrings(@PathVariable String moduleBaseName, HttpServletRequest request) {
    final String path =
            request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE).toString();
    final String bestMatchingPattern =
            request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE).toString();

    String arguments = new AntPathMatcher().extractPathWithinPattern(bestMatchingPattern, path);

    String moduleName;
    if (null != arguments && !arguments.isEmpty()) {
        moduleName = moduleBaseName + '/' + arguments;
    } else {
        moduleName = moduleBaseName;
    }

    return "module name is: " + moduleName;
}
like image 23
P.J.Meisch Avatar answered Sep 22 '22 04:09

P.J.Meisch