6

On Spring MVC rest service I am having issues trying to match anything that is beyond my configured RequestMapping value.

So for e.g. I have this:

@RequestMapping(value = "{configKey}/{arguments:.*}", method = RequestMethod.GET)

Which says that match anything that is beyond the second path variable. The problem is that this e.g. works ok with:

get("/test/document")

while this ends up with 404:

get("/test/document/download")

It is weird that Spring can't handle this regex. I actually tried a lot of solutions, but none of them worked.

Previously I had this configuration on JAX-RS:

@Path("/{configKey}/{arguments:.*}")

And everything was good, but now I am migrating and having this issue.

Does anyone know what's going on and how to fix this?

EDIT:

Adding {configKey}/** - doesn't work

Adding {configKey}/{arguments}/** works, but for e.g. if I call:

get("/test/document/download") I get only test as my config key and document as arguments. In the arguments I expect to get all what's beyond the {configKey}. Which can be anything for e.g. it should work in any case:

get("/test/document")
get("/test/document/download")
get("/test/document/download/1")
get("/test/document/download/1/2")
get("/test/whatever/xxx/1/2/etc")

Which was working with config for JAX-RS: @Path("/{configKey}/{arguments:.*}")

Aniket Kulkarni
  • 12,825
  • 9
  • 67
  • 90
Paulius Matulionis
  • 23,085
  • 22
  • 103
  • 143

3 Answers3

2

The following mapping should work for you

@RequestMapping(value = "{configKey}/**", method = RequestMethod.GET)

This mapping is known as default mapping pattern.

Spacemonkey
  • 1,725
  • 3
  • 20
  • 44
Master Slave
  • 27,771
  • 4
  • 57
  • 55
0

I found a workaround to it, it's not the permanent solution, I think it's a bug in Spring and I raised a Jira, but until it's fixed here it is:

I had to define my request mapping like this:

@RequestMapping(value = "{configKey}/**", method = RequestMethod.GET)

So basically match all what's after first variable in a path.

Then:

String arguments = pathMatcher.extractPathWithinPattern(
        request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE).toString(),
        request.getPathInfo());

Where a pathMatcher is an instance of AntPathMatcher used by Spring.

So now calling HTTP GET on for e.g. this path:

get("/test/leaderboard/user/mq/frankie1")

I have:

configKey = test
arguments = leaderboard/user/mq/frankie1
Paulius Matulionis
  • 23,085
  • 22
  • 103
  • 143
  • 2
    This jira is marked "Works as Designed", "Path variables in an @RequestMapping pattern cannot span multiple path segments.". So I think we cannot solve this problem, but to use query parameters instead. – cmicat Feb 11 '17 at 07:39
-1

Spring Use AntPathMatcher, The mapping matches URLs using the following rules:

1. ? matches one character
2. * matches zero or more characters
3. ** matches zero or more 'directories' in a path

This is how I configure request mapping url, I've test in my computer, and it works and You can custom based on your needs.

@RequestMapping(value = "/new-ajax/**", method = RequestMethod.GET)

Test case

/new-ajax/document/1
/new-ajax/document/download/1
/new-ajax/document/download/1/2
/new-ajax/test/whatever/xxx/1/2/etc
Adi Sembiring
  • 5,798
  • 12
  • 58
  • 70