user2432405
user2432405

Reputation: 1414

How to map several segments of URL to one PathVariable in spring-mvc?

I'm working on a webapp, one function of which was to list all the files under given path. I tried to map several segments of URL to one PathVariable like this :

@RequestMapping("/list/{path}")
public String listFilesUnderPath(@PathVariable String path, Model model) {
     //.... add the file list to the model
     return "list"; //the model name
}

It didn't work. When the request url was like /list/folder_a/folder_aa, RequestMappingHandlerMapping complained : "Did not find handler method for ..."

Since the given path could contains any number of segments, it's not practical to write a method for every possible situation.

Upvotes: 3

Views: 1854

Answers (2)

justfortherec
justfortherec

Reputation: 1650

You can capture zero or more path segments by appending an asterisk to the path pattern.

From the Spring documentation on PathPattern:

{*spring} matches zero or more path segments until the end of the path and captures it as a variable named "spring"

Note that the leading slash is part of the captured path as mentioned in the example on the same page:

/resources/{*path} — matches all files underneath the /resources/, as well as /resources, and captures their relative path in a variable named "path"; /resources/image.png will match with "path" → "/image.png", and /resources/css/spring.css will match with "path" → "/css/spring.css"

For your particular problem the solution would be:

@RequestMapping("/list/{*path}") // Use *path instead of path
public String listFilesUnderPath(@PathVariable String path, Model model) {
     //.... add the file list to the model
     return "list"; //the model name
}

Upvotes: 1

Predrag Maric
Predrag Maric

Reputation: 24433

In REST each URL is a separate resource, so I don't think you can have a generic solution. I can think of two options

  • One option is to change the mapping to @RequestMapping("/list/**") (path parameter no longer needed) and extract the whole path from request
  • Second option is to create several methods, with mappings like @RequestMapping("/list/{level1}"), @RequestMapping("/list/{level1}/{level2}"), @RequestMapping("/list/{level1}/{level2}/{level3}")... concatenate the path in method bodies and call one method that does the job. This, of course, has a downside that you can only support a limited folder depth (you can make a dozen methods with these mappings if it's not too ugly for you)

Upvotes: 4

Related Questions