Springmvc request parameter summary

prerequisite

When you use SpringMVC for development, you may encounter various types of request parameters on the front end. Here is a relatively comprehensive summary. The interface for handling controller parameters in SpringMVC is HandlerMethodArgumentResolver. This interface has many subclasses, which handle different (annotation types) parameters. Here are just a few subclasses:

  • RequestParamMethodArgumentResolver: used for parsing and processing Parameters annotated by @RequestParam, MultipartFile type parameters and Simple type (such as long, int) parameters.
  • RequestResponseBodyMethodProcessor: parse and process @RequestBody annotated parameters.
  • PathVariableMapMethodArgumentResolver: parse and process @PathVariable annotated parameters.

Actually, when parsing the request parameters of a controller, HandlerMethodArgumentResolverComposite is used, which contains all enabled HandlerMethodArgumentResolver subclasses. The HandlerMethodArgumentResolver subclass uses the HttpMessageConverter (actually a list for traversal matching analysis) subclass for matching analysis when parsing parameters, such as MappingJackson2HttpMessageConverter. The HandlerMethodArgumentResolver subclass depends on what HttpMessageConverter instance is actually determined by the ContentType in the request header (Uniformly named MediaType in SpringMVC, see org.springframework.http.MediaType), so we must process the request parameters of the controller before It is necessary to clarify what the ContentType of the external request is. The above logic can be directly seen from the source code AbstractMessageConverterMethodArgumentResolver#readWithMessageConverters, the idea is relatively clear. In the @RequestMapping annotation, produces and consumers are related to the ContentType of the request or response:

  • consumes: Specify the content type (ContentType) of the submitted content for processing the request, such as application/json, text/html , The request will be accepted only if it hits.
  • produces: Specify the type of content returned. Only when the specified type is included in the (Accept) type in the request header, it will be returned. If the returned JSON data is generally application/json;charset=UTF- 8.

In addition, SpringMVC uses Jackson as the JSON toolkit by default. If you do not fully understand the operation of the entire source code, it is generally not very recommended to modify the default MappingJackson2HttpMessageConverter (for example, some people like Use FastJson to implement HttpMessageConverter to introduce FastJson as a converter).

SpringMVC request parameter receiving

In fact, general form or JSON data requests are relatively simple, and some complex processing mainly includes URL path parameters , File upload, array or list type data, etc. In addition, regarding the existence of date type attributes in the parameter type (such as java.util.Date, java.sql.Date, java.time.LocalDate, java.time.LocalDateTime), it is generally necessary to customize the logic implementation String- >Date type conversion. In fact, the reason is very simple. Date-related types are not necessarily the same for every country, every time zone, or even every user. The following model classes are mainly used in some examples:

@Data public class User { private String name; private Integer age; private List contacts;}@Datapublic < span class="hljs-keyword">class Contact { private String name; private String phone;}

form parameter

non-object type single Parameter receiving:

This is the most commonly used form parameter submission, and the ContentType is specified as application/x-www-form-urlencoded, which means that URL encoding will be performed.

spmvc-p-1

Corresponding controller As follows:

@PostMapping(value = "/post")public String post(@RequestParam(name = "name") String name, @RequestParam (name = "age") Integer age) { String content = String.format( "name = %s,age = %d", name, age); log.info(content); return< /span> content;}

To be honest, if you have perseverance, all complex parameter submissions can eventually be converted into multiple single-parameter receptions, but doing so will generate a lot of redundant code. And the maintainability is relatively low. In this case, the parameter processor used is RequestParamMapMethodArgumentResolver.

Object type parameter receiving:

We then write an interface for submitting user information, using the models mentioned above, mainly including User name, age and contact information list. At this time, the final code of our target controller is as follows:

@PostMapping (value = "/user")public User saveUser(User user) { log.info(user.toString()); return user;}

We still specify the ContentType as application/x-www-form-urlencoded, and then we need to construct the request parameters:

spmvc-p-2

Because no annotations are used, the final parameter processor It is ServletModelAttributeMethodProcessor, which mainly encapsulates the form parameters in HttpServletRequest into MutablePropertyValues ​​instance, and then instantiates it through parameter type (creates User instance by constructing reflection), and fills in value by reflecting matching attributes. In addition, the list property request parameters in the request complex parameters look weird. In fact, they are written in the same way as adding the parameters that are finally mapped to the Map type in the .properties file. So, can the entire request parameters be stuffed in one field and submitted?

spmvc-p-3

No, because the actual submitted form, the key is user, and the value is actually a string. There is no String->User type converter. In fact, RequestParamMethodArgumentResolver relies on the Converter list in WebConversionService for parameter conversion:

< p>spmvc-p-4

There is still a solution, add an org .springframework.core.convert.converter.Converter can be implemented:

@Componentpublic class StringUserConverter implements Converter<String, User> { private static final ObjectMapper MAPPER = new ObjectMapper(); @Override public< /span> User convert(String source) { try {return MAPPER.readValue(source, User.class);} catch (IOException e) {throw new IllegalArgumentException(e);} }}

The above approach is a curve to save the country and is not recommended for use in a production environment, but if some third-party interface connection cannot avoid this parameter, you can choose this implementation method.

JSON parameter

Generally speaking, this method of directly POSTing a JSON string is more friendly to SpringMVC, you only need to set the ContentType to application/json, just submit an original JSON string:

spmvc-p-5

The code of the back-end controller is also relatively simple:

@PostMapping(value = "/user-2")public User saveUser2(@RequestBody User user) { log.info(user.toString()); < span class="hljs-keyword">return user;}

Because the @RequestBody annotation is used, the final parameter processor used is RequestResponseBodyMethodProcessor, which actually uses MappingJackson2HttpMessageConverter for parameter types The bottom layer depends on Jackson-related packages.

URL parameter

URL parameter, or request path parameter is a parameter obtained based on a URL template, for example, /user/{userId} is a URL template (The parameter placeholder in the URL template is {}), and the actual requested URL is /user/1, then by matching the actual requested URL and URL template, the userId can be extracted as 1. In SpringMVC, the path parameter in the URL template is called PathVariable, corresponding to the annotation @PathVariable, and the corresponding parameter processor is PathVariableMethodArgumentResolver. Note that @PathVariable’s parsing is based on the value (name) attribute for matching, which has nothing to do with the order of URL parameters. A simple example:

spmvc-p-6

< p>The background controller is as follows:

@GetMapping(value = " /user/{name}/{age}")public String findUser1(@PathVariable(value = "age") Integer age, @< span class="hljs-title">PathVariable(value = "name") String name) { String content = String.format("name = %s,age = %d", name, age); log.info(content ); return content;}

This usage is widely used in the software architecture style of Representational State Transfer (REST). I personally feel this style It is more flexible and clear (you can fully understand the meaning and function of the interface from the URL and request method). Two relatively special usage methods are introduced below.

Conditional URL parameters
In fact, path parameters support regular expressions. For example, when we use the /sex/{sex} interface, sex must be F( Female) or M(Male), then our URL template can be defined as /sex/{sex:M|F}, the code is as follows:

@GetMapping(value = "/sex/{sex:M|F}")public String findUser2(@PathVariable(value = "sex") String sex){ log.info(sex); return sex;} 

Only the request of /sex/F or /sex/M will enter the findUser2 controller method. Other requests for the path prefix are illegal and a 404 status code will be returned. Here is just an introduction to the simplest way to use URL parameter regular expressions. More powerful usage can be explored by yourself.

Use of @MatrixVariable
MatrixVariable is also a kind of URL parameter, corresponding to the annotation @MatrixVariable, but it is not a value in the URL (the value specified here is two The part between “/”), but a part of the value, it is separated by “;”, and KV is set by “=”. It is a bit abstract, for example: if we need to call a programmer whose name is doge, gender is male, and the group is code animal, the URL of the GET request can be expressed as: /call/doge;gender= male;group=programmer, the controller method we designed is as follows:

@GetMapping(value = < span class="hljs-string">"/call/{name}")public String find(@PathVariable(value = "name") String name, @MatrixVariable(value = "gender" ) String gender, @MatrixVariable(value = "group" ) String group) { String content = String.format("name = %s,gender = %s,group = %s" , name, gender, group); log.info(content); return content;}

Of course, if you follow the above Example of writing a good generation Code, try to request the interface and found that an error is reported: 400 Bad Request-Missing matrix variable ‘gender’ for method parameter of type String. This is because the @MatrixVariable annotation is not safe to use, and its support is disabled by default in SpringMVC. To enable support for @MatrixVariable, you need to set the RequestMappingHandlerMapping#setRemoveSemicolonContent method to false:

@Configurationpublic class CustomMvcConfiguration implements InitializingBean { @Autowired private RequestMappingHandlerMapping requestMappingHandlerMapping; @Override public void afterPropertiesSet () throws Exception { requestMappingHandlerMapping.setRemoveSemicolonContent(false); }} 

Unless there are special needs , Otherwise @MatrixVariable is not recommended.

File upload

When using POSTMAN to simulate the request for file upload, you need to select form-data, and submit it in POST:

< img alt="spmvc-p-8" src="/wp-content/uploads/images/opensource/spring/1626813537754.png" >

Assuming that we have an image file called doge on Disk D. jpg, now upload the file through the local service interface, the controller code is as follows:

@PostMapping(value = < span class="hljs-string">"/file1")public String file1(@RequestPart(name = "file1") MultipartFile multipartFile) { String content = String.format("name = %s,originName = %s,size = %d", multipartFile.getName(), multipartFile .getOriginalFilename(), multipartFile.getSize()); log.info(content); return content;}

The console output is:< /p>

name = file1,originName = doge.jpg,size = 68727< /pre> 

I may be a little confused, how did the parameters come, we can use Fildder to grab a package to see:

spmvc-p-7

It can be seen that the main attributes of the MultipartFile instance come from Content-Disposition, content-type and content-length respectively. In addition, InputStream is used to read the request The last part of the body (the byte sequence of the file). The parameter processor uses the RequestPartMethodArgumentResolver (remember that @RequestPart and MultipartFile must use this parameter processor). In other cases, using @RequestParam and MultipartFile or just using MultipartFile (the name of the parameter must be consistent with the name of the Content-Disposition description in the POST form) can also receive the uploaded file data, which is mainly parsed through RequestParamMethodArgumentResolver. The function of is more powerful, you can see its supportsParameter method for details. The controller method codes for these two cases are as follows:

@PostMapping(value = "/file2") public String file2(MultipartFile file1) { String content = String.format ("name = %s,originName = %s,size = %d", file1.getName(), file1.getOriginalFilename(), file1.getSize()) ; log.info(content); return content;}@PostMapping(value = "/file3")public String  file3(@RequestParam(name = "file1") MultipartFile multipartFile) { String content = String.format("name = %s,originName = %s,size = %d", multipartFile.getName(), multipartFile.getOriginalFilename(), multipartFile.getSize()); log. info(content); return content;}

Other parameters

Other parameters mainly include requests Header, Cookie, Model, Map and other related parameters, and some are not very commonly used or some relatively primitive attribute value acquisition (such as HttpServletRequest, HttpServletResponse, etc.) will not be discussed.

Request header

The value of the request header is mainly obtained through the @RequestHeader annotated parameter. The parameter processor is RequestHeaderMethodArgumentResolver, and the Key of the request header needs to be specified in the annotation . Simple and practical as follows:

spmvc-p-9

Controller method code:

@PostMapping(value = "/header" )public String header(@RequestHeader(name = "Content-Type") String contentType) { return contentType;}

Cookie value is mainly obtained through @CookieValue annotated parameter, the parameter processor is ServletCookieValueMethodArgumentResolver, The Key of the cookie needs to be specified in the comment. The controller method code is as follows:

@PostMapping(value = "/cookie ")public String cookie(@CookieValue(name = "JSESSIONID") String sessionId) { return sessionId;}

Model type parameter

The processor of Model type parameter is ModelMethodProcessor. Actually processing this parameter is It directly returns the Model (ModelMap type) in the ModelAndViewContainer instance. Because of the need to bridge the functions of different interfaces and classes, the callback instance is the BindingAwareModelMap type, which inherits from ModelMap and implements the Model interface. For example:

@GetMapping(value = "/model"< /span>)public String model(Model model, ModelMap modelMap) { log.info("{}", model == modelMap); return "success";}

Pay attention to calling this interface, the console will output Info The log content is: true. The attribute items added in ModelMap or Model will be attached to HttpRequestServlet and brought to the page for rendering.

@ModelAttribute parameter

The parameter processor of @ModelAttribute annotation processing is ModelAttributeMethodProcessor, the annotation of @ModelAttribute function source code is as follows:

 Annotation that binds a method parameter or method return value to< /span> a named model attribute, exposed to a web view.

Simple In other words, it is to bind method parameters or method return values ​​to Model (Map) in the form of key-value, distinguishing the following three situations:

  • 1, @ModelAttribute is used in the method (return value ), the method has no return value (void type), and the Model (Map) parameter needs to be set by yourself.
  • 2, @ModelAttribute is used in the method (return value), the method has a return value (non-void type), the return value will be added to the Model (Map) parameter, the key is specified by the value of @ModelAttribute, otherwise The return value type string will be used (the first letter becomes lowercase).
  • 3, @ModelAttribute is used in method parameters.

In a controller (using @Controller), if there are one or more methods that use @ModelAttribute, these methods are always executed before entering the controller method, and executed The order is determined by the loading order (the specific order is the priority without parameters, and is sorted in ascending order by the first letter of the method), for example:

@Slf4j@RestControllerpublic class ModelAttributeController { @ModelAttribute span> public void before(Model model) { log.info("before.... ......"); model.addAttribute("before", "beforeValue");} @ModelAttribute(value = "beforeArg") < span class="hljs-keyword">public String beforeArg()  {log.info("beforeArg.........."); return < span class="hljs-string">"beforeArgValue";} @GetMapping(value = "/modelAttribute ") public String modelAttribute(Model model, @ModelAttribute(value = "beforeArg") String beforeArg) { log.info( "modelAttribute.........."); log.info("beforeArg..... .....{}", beforeArg); log.info("{}", model); return "success";} @ModelAttribute public void after(Model model) { log. info("after.........."); model.addAttribute("after", "afterValue");} @ModelAttribute(value = "afterArg") public String afterArg() { log.info("afterArg.........."< /span>); return "afterArgValue"; }}

Call this interface , The console output log is as follows:

after..........
before...... .. ..
afterArg..........
beforeArg..........
modelAttribute..........
beforeArg..........beforeArgValue
{after=afterValue, before=beforeValue, afterArg=afterArgValue, beforeArg=beforeArgValue}< /pre>

The sorting rules and parameter settings and access can be confirmed.

Errors or BindingResult parameter

Errors is actually the parent interface of BindingResult. BindingResult is mainly used to call back the attribute items of JSR parameter verification exception. If JSR Validation exception, usually MethodArgumentNotValidException exception will be thrown, and 400 (Bad Request) will be returned, see the global exception handler DefaultHandlerExceptionResolver. The parameter processor of the Errors type is ErrorsMethodArgumentResolver. For example:

@PostMapping(value = "/errors"< /span>)public String errors(@RequestBody @Validated ErrorsModel errors, BindingResult bindingResult) { if (bindingResult.hasErrors()) {for (ObjectError objectError: bindingResult.getAllErrors()) {log.warn("name={},message={}"< /span>, objectError.getObjectName(), objectError.getDefaultMessage());}} return errors.toString();}//ErrorsModel@Data@NoArgsConstructor public class ErrorsModel { @NotNull(message = "id must not be null!" ) private Integer id; @NotEmpty(message = "errors name must not be empty!") private String name;}

The Warn log of calling the interface console is as follows:

name=errors,message=errors name must not be empty!

Under normal circumstances, it is not recommended to use this method to handle abnormal JSR validation attributes Item, because it will involve a lot of repetitive hard-coded work, it is recommended to directly inherit ResponseEntityExceptionHandler and override the corresponding method.

@Value parameter

The parameter of the controller method can be a parameter modified by the @Value annotation, which will assemble and convert the attribute value from the Environment to the corresponding parameter In the middle (that is, the source of the parameter is not the request body), the parameter processor is ExpressionValueMethodArgumentResolver. For example:

@GetMapping(value = "/value"< /span>)public String value(@Value(value = "${spring.application.name}") String name) { log. info("spring.application.name={}", name); return name;} 

Map type parameter

The range of Map type parameter is relatively wide, corresponding to a series of parameter processors, pay attention to the difference between using some of the annotations mentioned above Map type and Map type parameters that do not use annotations at all are handled differently. Here are a few relatively typical examples of Map type parameter processing.

Map parameters without any annotations
In this case, the parameters actually directly call back the ModelMap instance in ModelAndViewContainer, and the parameter processor is MapMethodProcessor. The attributes added to the Map parameter will be brought to the page.

Mapparameters annotated with @RequestParam
In this case, the parameter processor is RequestParamMapMethodArgumentResolver, and the request method used needs to specify the ContentType as x- www-form-urlencoded, application/json cannot be used:

spmvc-p-10

The controller code is:

@PostMapping(value = "/map")public String mapArgs(@RequestParam Map map) { log.info( "{}", map); return map.toString();}

Map with @RequestHeader annotation Parameter
In this case, the parameter processor is RequestHeaderMapMethodArgumentResolver, which is used to obtain the Key-Value of all request headers of the request.

Mapparameters annotated with @PathVariable
The parameter processor in this case is PathVariableMapMethodArgumentResolver, which is used to obtain all path parameters and encapsulate them as Key- Value structure.

MultipartFile collection-batch file upload

When uploading batch files, we generally need to receive a MultipartFile collection. There are two options:

  • 1. Use the MultipartHttpServletRequest parameter and directly call the getFiles method to get the MultipartFile list.
  • 2、使用@RequestParam注解修饰MultipartFile列表,参数处理器是RequestParamMethodArgumentResolver,其实就是第一种的封装而已。

spmvc-p-11

控制器方法代码如下:

@PostMapping(value = "/parts")public String partArgs(@RequestParam(name = "file") List parts) {    log.info("{}", parts);    return parts.toString();}

日期类型参数处理

日期处理个人认为是请求参数处理中最复杂的,因为一般日期处理的逻辑不是通用的,过多的定制化处理导致很难有一个统一的标准处理逻辑去处理和转换日期类型的参数。不过,这里介绍几个通用的方法,以应对各种奇葩的日期格式。下面介绍的例子中全部使用Jdk8中引入的日期时间API,围绕java.util.Date为核心的日期时间API的使用方式类同。

一、统一以字符串形式接收

这种是最原始但是最奏效的方式,统一以字符串形式接收,然后自行处理类型转换,下面给个小例子:

@PostMapping(value = "/date1")public String date1(@RequestBody UserDto userDto) {    UserEntity userEntity = new UserEntity();    userEntity.setUserId(userDto.getUserId());    userEntity.setBirthdayTime(LocalDateTime.parse(userDto.getBirthdayTime(), FORMATTER));    userEntity.setGraduationTime(LocalDateTime.parse(userDto.getGraduationTime(), FORMATTER));    log.info(userEntity.toString());    return "success";}@Datapublic class UserD to {    private String userId;    private String birthdayTime;    private String graduationTime;}@Datapublic class UserEntity {    private String userId;    private LocalDateTime birthdayTime;    private LocalDateTime graduationTime;}

spmvc-p-12

二、使用注解@DateTimeFormat或者@JsonFormat

@DateTimeFormat注解配合@RequestBody的参数使用的时候,会发现抛出InvalidFormatException异常,提示转换失败,这是因为在处理此注解的时候,只支持form提交(ContentType为x-www-form-urlencoded),例子如下:

spmvc-p-13

@Datapublic class UserDto2 {    private String userId;    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")    private LocalDateTime birthdayTime;    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")    private LocalDateTime graduationTime;}@PostMapping(value = "/date2")public String date2(UserDto2 userDto2) {    log.info(userDto2.toString ());    return "success";}//或者像下面这样@PostMapping(value = "/date2")public String date2(@RequestParam("name"="userId")String userId, @RequestParam("name"="birthdayTime") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime birthdayTime, @RequestParam("name"="graduationTime") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime graduationTime) {    return "success";}

而@JsonFormat注解可使用在form或者Json请求参数的场景,因此更推荐使用@JsonFormat注解,不过注意需要指定时区(timezone属性,例如在中国是东八区"GMT+8"),否则有可能导致出现"时差",举个例子:

@PostMapping(value = "/date2")public String date2(@RequestBody UserDto2 userDto2) {    log.info(userDto2.toString());    return "success";}@Datapublic class UserD to2 {    private String userId;    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")    private LocalDateTime birthdayTime;    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")    private LocalDateTime graduationTime;}

三、Jackson序列化和反序列化定制

因为SpringMVC默认使用Jackson处理@RequestBody的参数转换,因此可以通过定制序列化器和反序列化器来实现日期类型的转换,这样我们就可以使用application/json的形式提交请求参数。这里的例子是转换请求Json参数中的字符串为LocalDateTime类型,属于Json反序列化,因此需要定制反序列化器:

@PostMapping(value = "/date3")public String date3(@RequestBody UserDto3 userDto3) {    log.info(userDto3.toString());    return "success";}@Datapublic class UserDto3 {    private String userId;    @JsonDeserialize(using = CustomLocalDateTimeDeserializer.class)    private LocalDateTime birthdayTime;    @JsonDeserialize(using = CustomLocalDateTimeDeserialize r.class)    private LocalDateTime graduationTime;}public class CustomLocalDateTimeDeserializer extends LocalDateTimeDeserializer {    public CustomLocalDateTimeDeserializer() {        super(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));    }}

四、最佳实践

前面三种方式都存在硬编码等问题,其实最佳实践是直接修改MappingJackson2HttpMessageConverter中的ObjectMapper对于日期类型处理默认的序列化器和反序列化器,这样就能全局生效,不需要再使用其他注解或者定制序列化方案(当然,有些时候需要特殊处理定制),或者说,在需要特殊处理的场景才使用其他注解或者定制序列化方案。使用钩子接口Jackson2ObjectMapperBuilderCustomizer可以实现ObjectMapper的属性定制:

@Beanpublic Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer(){    return customizer->{        customizer.serializerByType(LocalDateTime.class,new LocalDateTimeSerializer(                DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));        customizer.deserializerByType(LocalDateTime.class,new LocalDateTimeDeserializer(                DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));    };}

这样就能定制化MappingJackson2HttpMessageConverter中持有的ObjectMapper,上面的LocalDateTime序列化和反序列化器对全局生效。

请求URL匹配

前面基本介绍完了主流的请求参数处理,其实SpringMVC中还会按照URL的模式进行匹配,使用的是Ant路径风格,处理工具类为org.springframework.util.AntPathMatcher,从此类的注释来看,匹配规则主要包括下面四点:

  • 1、?匹配1个字符。
  • 2、*匹配0个或者多个字符
  • 3、**匹配路径中0个或者多个目录
  • 4、{spring:[a-z]+}将正则表达式[a-z]+匹配到的值,赋值给名为spring的路径变量。

举些例子:

?形式的URL

@GetMapping(value = "/pattern?")public String pattern() {    return "success";}/pattern  404 Not Found/patternd  200 OK/patterndd  404 Not Found/pattern/  404 Not Found/patternd/s  404 Not Found

*形式的URL

@GetMapping(value = "/pattern*")public String pattern() {    return "success";}/pattern  200 OK/pattern/  200 OK/patternd  200 OK/pattern/a  404 Not Found

**形式的URL

@GetMapping(value = "/pattern/**/p")public String pattern() {    return "success";}/pattern/p  200 OK/pattern/x/p  200 OK/pattern/x/y/p  200 OK

{spring:[a-z]+}形式的URL

@GetMapping(value = "/pattern/{key:[a-c]+}")public String pattern(@PathVariable(name = "key") String key) {    return "success";}/pattern/a  200 OK/pattern/ab  200 OK/pattern/abc  200 OK/pattern  404 Not Found/pattern/abcd  404 Not Found

上面的四种URL模式可以组合使用,千变万化。

URL匹配还遵循精确匹配原则,也就是存在两个模式对同一个URL都能够匹配成功,则选取最精确的URL匹配,进入对应的控制器方法,举个例子:

@GetMapping(value = "/pattern/**/p")public String pattern1() {    return "success";}@GetMapping(value = "/pattern/p")public String pattern2() {    return "success";}

上面两个控制器,如果请求URL为/pattern/p,最终进入的方法为pattern2

最后,org.springframework.util.AntPathMatcher作为一个工具类,可以单独使用,不仅仅可以用于匹配URL,也可以用于匹配系统文件路径,不过需要使用其带参数构造改变内部的pathSeparator变量,例如:

AntPathMatcher antPathMatcher = new AntPathMatcher(File.separator);

小结

笔者在前一段时间曾经花大量时间梳理和分析过Spring、SpringMVC的源码,但是后面一段很长的时间需要进行业务开发,对架构方面的东西有点生疏了,毕竟东西不用就会生疏,这个是常理。这篇文章基于一些SpringMVC的源码经验总结了请求参数的处理相关的一些知识,希望帮到自己和大家。

参考资料:

  • spring-boot-web-starter:2.0.3.RELEASE源码。

(本文完)

Leave a Comment

Your email address will not be published.