2

I have some problem with slashes in variable thats hould be send in url. For example id could be like this:

ID: /gfdge1/DkxA8P+jYw43
URL: localhost:8080/find-user//gfdge1/DkxA8P+jYw43

"error": "Internal Server Error",
    "exception": "org.springframework.security.web.firewall.RequestRejectedException",
    "message": "The request was rejected because the URL was not normalized.",

because of this slash on first place it make problem

Before that i had problems with these slash in middle of ID but I've solved that with this code:

   @RequestMapping(name = "Get user data by ID", value = "/find-user/{userId}/**", method = RequestMethod.GET)
    @ResponseBody
    public User getUserData(@PathVariable String userId, 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 id="";
        if (null != arguments && !arguments.isEmpty()) {
            id = userId + '/' + arguments;
        } else {
            id = userId;
        }
        return userService.getUserData(id);
    }

but this doesn't work for this case when slash is on first place. I've also try to user RequestParam instead of PathVariable, but it have problems with some special characters for example when I user RequestParam it replace '+' with empty space,...

Does anyone can help me how to solve this problem?

1 Answers1

3

Its an inherent issue with using Strings as path variables, it's not an issue with your code but how the HTTP request is interpreted so you can't do anything in your code to make this work.

You do have some options though:

  1. Ensure the values you use cannot be created with special characters such as "/"
  2. Avoid using Strings in path variables completely.

I lean more towards 2 as maintaining 1 for all possible problem characters/strings is pretty messy and unnecessary.

To do 2 correctly you should consider having all your REST getters finding their related entities by a numeric ID only e.g.

localhost:8080/find-user/3

If you need to add additional search parameters e.g. username in your case then you should use something like QueryDSL to create a predicate of search parameters which are passed as query parameters instead of path variables e.g.:

localhost:8080/find-user?username=/gfdge1/DkxA8P+jYw43

Plog
  • 9,164
  • 5
  • 41
  • 66