What is the meaning of {id:.+} in a Spring MVC req

2020-02-08 07:09发布

问题:

I came across a method in the controller. What is this id:.+ ??

@RequestMapping(value="/index/{endpoint}/{type}/{id:.+}", method=RequestMethod.POST, consumes=kContentType, produces=kProducesType)
@ResponseBody
public String indexData(@PathVariable(value="endpoint") String endpoint, @PathVariable(value="type") String type, @PathVariable(value="id") String id, @RequestBody String body, HttpServletRequest request) {
    logger.debug("In web controller for endpoint " + endpoint);
    return indexController.indexData(endpoint, type, id, body,  getSecurityContextProvider(request));
}

回答1:

The syntax of a path variable in a spring MVC controller requestmapping is {variable_name:regular_expression}. You can optionally omit the regular expression, which leads to what you see more often, {id}.

So, for the example /index/{endpoint}/{type}/{id:.+} the variable name is id and the regular expression is .+ (see below reference to spring docs).

The regular expression .+ is stating "match the metacharacter . one or more times". The '.' metacharacter represents any character including white space (though some implementations will not match newlines). See http://en.wikipedia.org/wiki/Regular_expression

The regular expression is being used to help Spring determine the value of the variable because you can have complex variable names or there might be other important information at the end of the path that would otherwise get sucked into the variable value if Spring just said "go until the end of the path" (eg. filename extensions or path variables).

It's possible that in your example, the id variable can contain special characters that would otherwise cause Spring to terminate the variable prematurely. I've run into this problem before when trying to use a filename that contained a file extension (foobar.jpg). Spring would return only the "foobar" part of the variable because Spring was assuming I wanted it to terminate the variable value at the period delimiter. So, in this case, to make sure that "id" matches the full value, you put the regex that tells Spring to go ahead and match everything between the last forward slash and the end of the path. SO Reference: Spring MVC @PathVariable getting truncated

Here's the excerpt from the Spring docs that deals with complex variable matching:

Sometimes you need more precision in defining URI template variables. Consider the URL "/spring-web/spring-web-3.0.5.jar". How do you break it down into multiple parts?

The @RequestMapping annotation supports the use of regular expressions in URI template variables. The syntax is {varName:regex} where the first part defines the variable name and the second - the regular expression."

Here is their (fairly complex) example:

@RequestMapping("/spring-web/{symbolicName:[a-z-]+}-{version:\\d\\.\\d\\.\\d}{extension:\\.[a-z]+}")
public void handle(@PathVariable String version, @PathVariable String extension) {
    // ...
}

Source: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html

The example they provide shows how you perform complex mappings from requests to controller method paramters that you wouldn't be able to without using a regular expression.