Spring MVC 绑定请求包中的数据

1. 前言

Spring MVC 框架的目的是为了解放开发者,让开发者更专注于核心逻辑,它提供了很多辅助性功能模块,来提高开发者的开发效率。

本节课将和大家一起讲解 Spring MVC 是如何使用下面的几个注解解析请求包中的数据。

  • @RequestParam ;
  • @CookieValue;
  • @RequestHeader;
  • @PathVariable 。

本章节的重点就是你要记住它们的使用场景。

2. 使用注解解析数据

原生 Servlet 开发过程中,开发者定义的 Servlet 具有请求响应功能。因为 J2EE 中的 Servlet 仅仅只是提供了编写企业级应用程序的规范,并没有提供更多实质性的功能。在执行响应逻辑之前或之后需要开发者编写一些通用的功能代码。

如解析请求包中的数据、构建响应路径……

Spring MVC 提供了很多实用的注解,用来解析请求包、自动绑定请求包中不同位置的数据。在使用注解解析请求包中的数据前,先了解一下请求包的格式。

WEB 应用程序中, 所谓的请求包是指遵循 HTTP 协议的一种数据格式包。在某些文章中,称请求包为报文。

图片描述

一个完整的请求包应该由 3 个部分组成:

  • 请求行: 包括请求方法、请求的资源地址(URL) 、HTTP 协议版本号;
  • 消息头: 消息头是传送给服务器的信息,以 key:value 的格式描述;
  • 实体部分或报文体:key=value 的数据格式保存客户端传递给应用程序的数据。

2.1 @RequestParam

功能: 自动绑定请求包中的请求参数中的值。

请求参数可以出现在请求包中的 2 个位置:

  • ? 的方式附加在 URL 后面。如 http://localhost:8888/saveUser?name=abc 。name 就是请求参数,abc 是值;
  • 以类似于 name=abc 的方式存储在请求包的报文体中(实体部分)。

Tips: 当客户端以 POST 方法请求时,数据将存储在实体部分。

实例:

@RequestMapping(value="/saveUser")
public String save(@RequestParam("userName") String userName,@RequestParam("password")  password){}

当请求格式类似于 http://localhost:8888/saveUser?userName=abc&password=123456 时,save()方法中的 userNamepassword 2 个参数会被分别注入 abc 和 123456 这 2 个值。

客户端在表单中以 POST 方法发送请求时,数据将会以 userName=abc&password=123456 的格式存放在请求包的实体部分,也会自动注入到 save() 方法的参数中。

Tips: 一定要保证 @RequestParam(“参数名”) 中的 “参数名” 和请求包中的参数名的命名相同。

@RequestParam 注解中有 3 个常用的属性:

  • value(): 指定要解析的请求包中的参数名;
@AliasFor("name")
String value() default "";
  • required(): 表示请求包中是否必须存在由 value() 指定的参数名,默认值是 true。如果没有此参数则会抛出异常;
boolean required() default true;
  • defaultValue(): 表示如果不能正确获取到指定参数的值时,则提供一个默认值。设置该参数时,自动将 required 设为 false
String defaultValue() default ValueConstants.DEFAULT_NONE;

综合实例:

@RequestMapping(value="/saveUser")
public String save(@RequestParam(value = "userName",defaultValue="mk",required = false)  String userName,){
}

Tips: 当不能确定是否存在名为 “userName” 的参数时,可使用 defaultValue 提供默认值,并设置 required 为 false。

2.2 @CookieValue

功能描述: @CookieValue 用来自动绑定请求包中的 Cookie 值。

Cookie 一般由 WEB 应用程序在服务器端创建,通过响应包传递给浏览器,并可以在浏览器端以文件的形式存储。在后续请求过程中,请求包又可以携带此 Cookie 返回给服务器。

Cookie 所能保存的数据量有限且只能是字符类型,但其应用场景较多,如 WEB 程序中的 Session 组件的状态维护、用户免输入登录、历史记录显示等功能都可以通过 Cookie 实现。

如果要获取请求包中的 Cookie 中的值,控制器中只需要如下编码便可:

@RequestMapping(value="/sessionId")
public String getSessionId(@CookieValue("JSESSIONID") String sessionId){

}

当请求格式类似于 http://localhost:8888/saveUser?sessionId 时,getSessionId()方法中的 sessionId 参数会被注入 Cookie 中所携带的 JSESSIONID 的值。

只要指定 Cookie 的名称,@CookieValue 便能自动获取此 Cookie 的值。

2.3 @RequestHeader

功能描述: 请求包中有很多消息头信息,都是以 key:value 的格式存在。在开发过程中,当需要获取这些消息头信息时,可以使用 @RequestHeader 注解自动绑定。

实例:

@RequestMapping(value="/header")
public String getHeader(@RequestHeader("Accept-Language") String accpetLanguage){
  ...
}

当请求格式类似于 http://localhost:8888/header 时,**getHeader()**方法的 accpetLanguage 参数会被注入请求包中 key 名为 Accept-Language 的消息头值。

当然,你可以更改成你所需要的消息头的 key 名,然后获取其对应的值。

@RequestHeader 注解中的方法如下:

@AliasFor("name")
String value() default "";
String name() default "";
boolean required() default true;
String defaultValue() default ValueConstants.DEFAULT_NONE;

其功能和 @RequestMapping 注解中的一样。两者只是关心的请求包中的数据不同而已。

2.4 @PathVariable

功能描述: @PathVariable 注解用来获取 URL 中变量的值。

什么是 URL 中的变量?还是用一个实例来说话:

@RequestMapping("/user/{userId}")
public String getUserById(@PathVariable("userId") String userId){

}

{userId} 就是变量占位符。具体请求时,可使用一个真实值替换。如请求格式:http://localhost:8888/user/1 时,@PathVariable 可以为 getUserById() 方法中的 userId 参数注入值 1。

@PathVariable 注解同样有一个 required 属性,表示是否强制 URL 中有变量的存在。

boolean required() default true;

@PathVariable 注解非常有用,请你一定要记住它。

3. 小结

本节向大家介绍了 4 个注解,大家可以使用它们很轻松的从请求包中解析自己所需要的数据。

这 4 个注解的使用方式大同小异,每一种注解各自关注了请求包中不同位置的数据:

  • @RequestParam :关注请求参数中的值;
  • @CookieValue:关注 Cookie 的值;
  • @RequestHeader 关注请求头的值;
  • @PathVariable :关注请求变量的值。