概要
处理方法参数绑定常用的注解,我们根据他们处理的Request的不同内容部分分为三大类
- 处理request header部分的注解: @RequestHeader, @CookieValue;
- 处理request body部分的注解:@RequestParam, @RequestBody;
- 处理attribute类型是注解: @SessionAttributes, @ModelAttribute;
一、@RequestParam(重点)
作用
在处理方法入参处使用 @RequestParam 可以把请求参数传递给请求方法,
- 当客服端请求的参数名跟请求方法的参数名字不一样时可以使用,
- 当客服端必传参数的时候
- 还有就是需要给参数赋默认值的时候
源码
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
@AliasFor("name")
String value() default "";
@AliasFor("value")
String name() default "";
boolean required() default true;
String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
}
属性
属性 | 说明 |
---|---|
String value() | 请求参数中的名称,等同于name |
boolean required() | 请求参数中是否必须提供此参数。默认值:true。表示必须提供,如果不提供将报错。 |
String defaultValue() | 提供默认值 |
栗子
给参数起别名
@Controller
@RequestMapping("/params")
public class RequestParamController {
@RequestMapping("/test1")
public String method1(@RequestParam(value = "name") String username) {
System.out.println(username);
return "参数别名"
}
}
//请求地址 /params/test1?name='乔碧萝殿下'
使用默认值参数
@RestController
@RequestMapping("/params")
public class RequestParamController {
// 请求地址 /params/test2?page=1 或者/params/test2?page=1&size=10
@RequestMapping("/test2")
public String method2(@RequestParam(value = "page", defaultValue = "1") int page ,
@RequestParam(value = "size",required = false,defaultValue = "10") int size) {
System.out.println(page);
System.out.println(size);
return "使用默认值参数+可选参数";
}
}
二、@RequestBody(重点)
作用
该注解用于读取Request请求的body部分数据(get请求没有请求体,所以不能使用)
应用场景是POST
或者PUT
的数据是JSON格式或者XML格式,而不是普通的键值对形式
注意
单个参数不用加@RequestBody、可以用@RequestParam
源码
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestBody {
boolean required() default true;
}
属性
参数 | 说明 |
---|---|
boolean required() | 是否必须有请求体。默认值是:true。当取值为 true 时, |
前期准备工作
导入包默认使用jackson转化
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.5</version>
</dependency>
集成fastjson
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
</dependency>
配置转化器
<!-- 设置配置方案 -->
<mvc:annotation-driven>
<!-- 消息转化器 -->
<mvc:message-converters register-defaults="false">
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<!-- 加入支持的媒体类型:返回contentType -->
<property name="supportedMediaTypes">
<list>
<!-- 这里顺序不能反,一定先写text/html,不然IE下会出现下载提示 -->
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
<property name="fastJsonConfig">
<bean class="com.alibaba.fastjson.support.config.FastJsonConfig">
<property name="features">
<list>
<value>AllowArbitraryCommas</value>
<value>AllowUnQuotedFieldNames</value>
<value>DisableCircularReferenceDetect</value>
</list>
</property>
<!--配置特定的日期格式-->
<property name="dateFormat" value="yyyy-MM-dd HH:mm:ss"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
@Controller
public class ResponseBodyController {
@RequestMapping("/body")
@ResponseBody
public Shop testResponseBody() {
Shop shop = new Shop();
shop.setShopId(1);
shop.setName("娃娃");
shop.setTitle("白天么么哒,晚上怕怕怕");
return shop;
}
}
JSONField
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER })
public @interface JSONField {
// 配置序列化和反序列化的顺序,1.1.42版本之后才⽀持
int ordinal() default 0;
// 指定序列化字段的名称
String name() default "";
// 指定字段的格式,对⽇期格式有⽤
String format() default "";
// 是否序列化
boolean serialize() default true;
// 是否反序列化
boolean deserialize() default true;
}
public class Shop implements Serializable {
private Integer shopId;
private String name;
private String title;
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date createDate;
}
栗子
基本使用
@Controller
@RequestMapping("/body")
public class RequestBodyController {
@RequestMapping(value = "/test1", method = RequestMethod.POST)
public String method1(@RequestBody String name) {
// 获取的是json字符串
System.out.println(name);
return "请求体参数";
}
}
自动解析成对象
// java bean
public class Shop implements Serializable {
private Integer shopId;
private String name;
private String title;
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date createDate;
... 省略其它
}
// 控制层
@RestController
@RequestMapping("/shop")
public class ShopController {
@RequestMapping(value = "/add",method = RequestMethod.POST)
public Shop add(@RequestBody Shop shop) {
// 数据库保存
return shop;
}
}
<script>
$(function () {
const SHOP_URL = "http://localhost:8080/shop/add";
/*定义字面量对象*/
let shop = {
name: "娃娃",
title: "白天么么哒"
};
let data = JSON.stringify(shop);
$.ajax(SHOP_URL, {
type: "POST",
data: data,
dataType:"json",
contentType:"application/json",
success:function (results) {
alert(results)
}
})
})
</script>
三、@RequestHeader(掌握)
作用
可以把Request请求header部分的值绑定到方法的参数上。
源码
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestHeader {
@AliasFor("name")
String value() default "";
@AliasFor("value")
String name() default "";
boolean required() default true;
String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
}
属性
属性 | 说明 |
---|---|
String value() | 请求参数中的名称,等同于name |
boolean required() | 请求参数中是否必须提供此参数。默认值:true。表示必须提供,如果不提供将报错。 |
String defaultValue() | 提供默认值 |
栗子
@RestController
public class RequestHeaderController {
@RequestMapping(value = "/getHeader", method = RequestMethod.GET)
public String getHeader(
@RequestHeader("Host") String host,
@RequestHeader("User-Agent") String userAgent,
@RequestHeader("Accept") String accept,
@RequestHeader("Accept-Language") String acceptLanguage,
@RequestHeader("Accept-Encoding") String acceptEncoding,
@RequestHeader("Connection") String conn) {
System.out.println(host);
System.out.println(userAgent);
System.out.println(accept);
System.out.println(host);
return "请求头参数";
}
}
四、@CookieValue(掌握)
作用
用来获取Cookie中的值
源码
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface CookieValue {
@AliasFor("name")
String value() default "";
@AliasFor("value")
String name() default "";
boolean required() default true;
String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
}
属性
属性 | 说明 |
---|---|
String value() | 请求参数中的名称, 等同于name |
boolean required() | 请求参数中是否必须提供此参数。默认值:true。表示必须提供,如果不提供将报错。 |
String defaultValue() | 提供默认值 |
栗子
@RestController
public class RequestHeaderController {
@RequestMapping(value="/getHeader")
public String getHeader(
@CookieValue("JSESSIONID") String sessionId){
return "获取Cookie中的参数";
}
}
五、@SessionAttributes(了解)
作用
若希望在多个请求之间共用数据,则可以在控制器类上标注一个 @SessionAttributes,配置需要在session中存放的数据范围,Spring MVC将存放在model中对应的数据暂存到 HttpSession对象中
除了可以通过属性名指定需要放到会话中的属性外,还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中
源码
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface SessionAttributes {
@AliasFor("names")
String[] value() default {};
@AliasFor("value")
String[] names() default {};
Class<?>[] types() default {};
}
属性
属性 | 说明 |
---|---|
String value() | 请求参数中的名称, 等同于names |
Class<?>[] types() | 模型属性的对象类型指定哪些模型属性需要放到会话中 |
栗子
配合Model使用
public class User implements Serializable {
private Integer uid;
private String name;
}
public class SessionTypesTest {
private String key;
private String value;
}
@Controller
@SessionAttributes(value = {"hello","user"} , types=SessionTypesTest.class)
public class SessionAttributesController {
@RequestMapping("/session")
public String add(Model model) {
// 基本类型
model.addAttribute("hello", "world");
// 对象
User user = new User();
user.setUid(1);
user.setName("admin");
model.addAttribute(user);
return "在session添加值";
}
@RequestMapping("/session/attributes")
@ResponseBody
public String sessionAttributesMsg(HttpSession session) {
User user = (User) session.getAttribute("user");
System.out.println(user.getUid());
System.out.println(user.getUid());
return "从session中获取值";
}
}
// 先访问/session 设置值
// 在访问 /session/attributes 获取session中的属性
指定类型
@Controller
// value跟type是并集关系
@SessionAttributes(value = {"user"}, types = {User.class})
public class SessionAttributesController {
@RequestMapping(value = "/session/types")
public String test(Model model) {
User user = new User(1,"admin");
model.addAttribute("user", user);
return "session中添加指定类型";
}
@RequestMapping("/session/types/get")
@ResponseBody
public User test2(@ModelAttribute("user") User user){
return user
}
}
六、@SessionAttribute(掌握)
作用
引用Session中的某个属性, 在某个方法参数中,绑定参数,从而在方法中直接使用其值
源码
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SessionAttribute {
@AliasFor("name")
String value() default "";
@AliasFor("value")
String name() default "";
boolean required() default true;
}
属性
属性 | 说明 |
---|---|
String value() | 一个字符串。里面应写需要存储到session中数据的名称。等价于name |
boolean required() | 是否必要,请求的session中必须包含该字段 |
栗子
设置Session数据
七、@ModelAttribute(了解)
作用
用在请求方法上,也可以用在参数上面
- 在方法上,表示当前方法会在控制器的方法执行之前,先执行。它可以修饰没有返回值的方法,也可以修饰有具体返回值的方法。
- 出现在参数上,获取指定的数据给参数赋值。
备注
@ModelAttributes 在类上使用 - 在类上使用的使用修饰的方法在其他方法执行前先执行。在调用所有方法之前先执行@ModelAttribute标记的方法,谨慎使用
应用场景
当表单提交数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库对象原来的数据。
源码
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ModelAttribute {
@AliasFor("name")
String value() default "";
@AliasFor("value")
String name() default "";
boolean binding() default true;
}
属性
属性 | 说明 |
---|---|
String value() | 用于获取数据的 key。key 可以是 POJO 的属性名称,也可以是 map 结构的 key |
栗子
ModelAttribute 无返回值
@RestController
public class ModelAttributeController {
@ModelAttribute
public void showModel(User user) {
System.out.println("执行了 showModel 方法"+user.getName());
}
@RequestMapping("/testModelAttribute")
public String testModelAttribute(User user) {
System.out.println("执行了控制器的方法"+user.getName());
return "模型属性控制";
}
}
网友评论