SpringMVC笔记(2)-@RequestMapping与请求参数获取

@RequestMapping注解

介绍

在控制器方法中,我们会使用@RequestMapping注解来说明该方法匹配的请求路径,该注解的功能也就是将请求和处理请求的控制器方法进行关联,建立起映射关系。SpringMVC接收到指定的请求之后,就会在映射关系中找到对应的控制器方法来处理这个请求。

@RequestMapping注解可以用来标识一个类,也可以用来标识一个方法

  • 标识类:设置请求路径的初始信息
  • 标识方法:设置请求路径的具体信息

如果一个控制器被该注解标识了,那么它的方法对应的实际完整路径应该要加上类注解中的路径。

属性

下面介绍@RequestMapping中的相关属性。

首先是value属性。@RequestMapping注解的value属性用来指定匹配的请求地址。这是一个字符串数组,表示该请求方法能够匹配多个请求地址。

1
@RequestMapping(value={"/test1","/test2"})

method属性表示通过请求的请求方式来进行匹配。这是一个RequestMethod类型的数组,表示该请求方法能够匹配的请求对应的请求方式。

1
2
3
4
@RequestMapping(
value = "test",
method = {RequestMethod.GET, RequestMethod.POST}
)

结合请求方式的不同,SpringMVC中提供了一系列基于@RequestMapping的派生注解,用来处理不同的请求,如下所示,基本都能见名知义:

  • 处理get请求:@GetMapping
  • 处理post请求:@PostMapping
  • 处理put请求:@PutMapping
  • 处理delete请求:@DeleteMapping

params属性表示通过请求的请求参数来匹配请求。这是一个字符串类型的数组,其中每一个字符串都是一个表达式。浏览器发送的请求,只有当它的参数满足params属性中全部表达式时,才能被响应。表达式主要有如下四种:

  1. param:请求必须携带param参数
  2. !param:请求不能携带param参数
  3. param=value:请求必须携带param参数,并且值必须为value
  4. param!=value:请求可以不携带param参数,如果携带值那么值不能为value

例如下面的例子,能够被响应的请求,应该满足参数必须携带username,不能携带password,必须携带age且值为18,可以携带email,如果携带了值不能为haha@haha.com

1
2
3
4
@RequestMapping(
value = "/test",
params = {"username", "!password", "age=18", "email!=haha@haha.com"}
)

headers属性和params属性基本类似,它通过请求的请求头信息来匹配。该属性也是一个字符串类型的数组,也可以通过上面相同的四种表达式来决定约束条件。

SpringMVC支持ant风格的路径,具体如下:

  • ?:表示任意的单个字符
  • *:表示任意的0个或者多个字符,但是不能跨目录层级
  • **:表示任意层数的任意目录

但是在使用的过程中需要注意,在url中,?是请求链接和参数的分隔符,不能被匹配;/表示一层新的目录,不能被匹配。

路径占位符

SpringMVC同样支持路径的占位符,简单来说就是通过参数形式解析链接中的值。这种方式在获取REST方式的请求参数时非常方便。REST方式的请求中会将请求参数作为路径的一部分,举例来说,我们利用可以结合参数访问如下请求/testRest?id=123&username=root,这也是我们一开始接触的方式,即路径与参数分离,而采用REST方式的话,请求可能就是/testRest/123/root

通过路径的占位符,我们可以获取REST方式请求中的参数:

1
2
3
4
5
6
7
8
@RequestMapping("/testRest/{id}/{username}")
public String testRest(@PathVariable String id, @PathVariable("username") String name) {
System.out.println(id);
System.out.println(name);
return "success";
}
// 访问/testRest/123/root
// 输出123 root

在路径中设置占位符之后,我们需要获取对应的值。通过注解@PathVariable,我们可以将路径中参数与形参进行绑定,之后就可以在代码中使用。我们可以在注解中指定要匹配路径中的哪一部分,如果没有指定,则默认按照形参名来匹配。

注意这里我们获取的不是实际意义上的参数,只是解析了路径中的内容作为我们的参数,实际意义上的参数还是指的整个链接中?后面的内容,这也是我们后面要介绍的内容。

请求参数获取

参数获取

下面我们介绍在SpringMVC中如何获取请求参数。主要指的是利用&拼接的参数,即get请求携带参数的样式。如果是post请求,请求体中的参数如果满足形式与get请求参数相同,也能够被解析。

通过ServletAPI获取

在JavaWeb中我们可以通过ServletAPI来获取请求参数,这里自然也可以。要使用相关对象,我们可以在控制器方法中增加对应类型的形参,如下所示。此时,HttpServletRequest类型的参数就表示封装了当前请求请求报文的对象,然后我们就可以通过对应方法获取到对应参数:

1
2
3
4
5
6
7
8
@RequestMapping("/testParam1")
public String testParam1(HttpServletRequest request) {
String id = request.getParameter("id");
String username = request.getParameter("username");
System.out.println(id);
System.out.println(username);
return "success";
}

通过形参获取

SpringMVC既然是对Servlet进行封装,那么自然是提供了更加方便的方式来获取请求参数。我们可以在控制器方法的形参位置,设置和请求参数同名的形参。这样当浏览器发送请求,匹配到对应方法的时候,在DispathcerServlet中就会将请求参数赋值给相应的形参:

1
2
3
4
5
6
@RequestMapping("/testParam2")
public String testParam2(Integer id, @RequestParam("username") String name) {
System.out.println(id);
System.out.println(name);
return "success";
}

默认情况下,我们可以通过设置同名形参来获取对应请求参数,而通过@RequestParam注解,我们可以指定更多的映射方式。

@RequestParam注解可以为请求参数和控制器方法的形参创建映射,其中一共有三个属性:

  • value:指定为该形参赋值的请求参数名称
  • required:设置是否必须传输此请求参数,默认值为true
  • defaultValue:设置该参数的默认值,如果没有传递或者传递为""时,则使用该默认参数值

注意这里,只有当没有设置defaultValue并且required指定为true的时候,不携带对应参数才会报错400。

如果请求参数含有多个同名的参数,我们可以在形参中设置字符串数组或者字符串类型的形参来接收这些参数:

  • 如果使用了字符串数组类型的形参,那么数组中包含了每一个数据
  • 如果使用了字符串类型的形参,那么该字符串的值为每个数据之间使用逗号拼接的结果

除了获取请求参数,我们也可以通过类似的方法来获取请求头信息或者是Cookie数据。相关功能对应不同的注解,相关注解如下:

  • @RequestHeader:为请求头信息和控制器方法形参创建映射关系
  • @CookieValue:为Cookei数据和控制器方法形参创建映射

注解的使用方式与@RequestParam基本相同,这里就不再多进行描述。

通过实体类获取

在请求参数过多的时候,如果全部写在形参中会非常繁琐。我们可以在控制器方法的形参位置设置一个实体类类型的形参,这样如果请求参数和实体类的属性名能够匹配的话,DispatcherServlet就会调用属性的set方法为其赋值。

1
2
3
4
5
@RequestMapping("/testParam3")
public String testParam3(User user) {
System.out.println(user);
return "success";
}

乱码问题解决

如果我们的是通过链接中参数进行传递,则不会出现中文乱码问题。但是如果我们的参数是通过post请求的请求体进行传递的,则会出现乱码问题。

乱码问题的解决也非常简单,只需要在web.xml中配置SpringMVC提供的编码过滤器CharacterEncodingFilter即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!--配置SpringMVC的编码过滤器-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

注意,SpringMVC处理编码的过滤器一定要配置在其他过滤器的前面,否则是没有效果的。


SpringMVC笔记(2)-@RequestMapping与请求参数获取
http://example.com/2022/10/17/SpringMVC笔记-2-RequestMapping与请求参数获取/
作者
EverNorif
发布于
2022年10月17日
许可协议