概要
處理方法參數(shù)綁定常用的注解,我們根據(jù)他們處理的Request的不同內(nèi)容部分分為三大類(lèi)
- 處理request header部分的注解: @RequestHeader, @CookieValue;
- 處理request body部分的注解:@RequestParam, @RequestBody;
- 處理attribute類(lèi)型是注解: @SessionAttributes, @ModelAttribute;
一、@RequestParam(重點(diǎn))
作用
在處理方法入?yún)⑻幨褂?@RequestParam 可以把請(qǐng)求參數(shù)傳遞給請(qǐng)求方法,
- 當(dāng)客服端請(qǐng)求的參數(shù)名跟請(qǐng)求方法的參數(shù)名字不一樣時(shí)可以使用,
- 當(dāng)客服端必傳參數(shù)的時(shí)候
- 還有就是需要給參數(shù)賦默認(rèn)值的時(shí)候
源碼
@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";
}
屬性
| 屬性 | 說(shuō)明 |
|---|---|
| String value() | 請(qǐng)求參數(shù)中的名稱(chēng),等同于name |
| boolean required() | 請(qǐng)求參數(shù)中是否必須提供此參數(shù)。默認(rèn)值:true。表示必須提供,如果不提供將報(bào)錯(cuò)。 |
| String defaultValue() | 提供默認(rèn)值 |
栗子
給參數(shù)起別名
@Controller
@RequestMapping("/params")
public class RequestParamController {
@RequestMapping("/test1")
public String method1(@RequestParam(value = "name") String username) {
System.out.println(username);
return "參數(shù)別名"
}
}
//請(qǐng)求地址 /params/test1?name='喬碧蘿殿下'
使用默認(rèn)值參數(shù)
@RestController
@RequestMapping("/params")
public class RequestParamController {
// 請(qǐng)求地址 /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 "使用默認(rèn)值參數(shù)+可選參數(shù)";
}
}
二、@RequestBody(重點(diǎn))
作用
該注解用于讀取Request請(qǐng)求的body部分?jǐn)?shù)據(jù)(get請(qǐng)求沒(méi)有請(qǐng)求體,所以不能使用)
應(yīng)用場(chǎng)景是POST或者PUT的數(shù)據(jù)是JSON格式或者XML格式,而不是普通的鍵值對(duì)形式
注意
單個(gè)參數(shù)不用加@RequestBody、可以用@RequestParam
源碼
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestBody {
boolean required() default true;
}
屬性
| 參數(shù) | 說(shuō)明 |
|---|---|
| boolean required() | 是否必須有請(qǐng)求體。默認(rèn)值是:true。當(dāng)取值為 true 時(shí), |
前期準(zhǔn)備工作
導(dǎo)入包默認(rèn)使用jackson轉(zhuǎn)化
<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>
配置轉(zhuǎn)化器
<!-- 設(shè)置配置方案 -->
<mvc:annotation-driven>
<!-- 消息轉(zhuǎn)化器 -->
<mvc:message-converters register-defaults="false">
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
<!-- 加入支持的媒體類(lèi)型:返回contentType -->
<property name="supportedMediaTypes">
<list>
<!-- 這里順序不能反,一定先寫(xiě)text/html,不然IE下會(huì)出現(xiàn)下載提示 -->
<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;
// 指定序列化字段的名稱(chēng)
String name() default "";
// 指定字段的格式,對(duì)?期格式有?
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 "請(qǐng)求體參數(shù)";
}
}
自動(dòng)解析成對(duì)象
// 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) {
// 數(shù)據(jù)庫(kù)保存
return shop;
}
}
<script>
$(function () {
const SHOP_URL = "http://localhost:8080/shop/add";
/*定義字面量對(duì)象*/
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請(qǐng)求header部分的值綁定到方法的參數(shù)上。
源碼
@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";
}
屬性
| 屬性 | 說(shuō)明 |
|---|---|
| String value() | 請(qǐng)求參數(shù)中的名稱(chēng),等同于name |
| boolean required() | 請(qǐng)求參數(shù)中是否必須提供此參數(shù)。默認(rèn)值:true。表示必須提供,如果不提供將報(bào)錯(cuò)。 |
| String defaultValue() | 提供默認(rèn)值 |
栗子
@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 "請(qǐng)求頭參數(shù)";
}
}
四、@CookieValue(掌握)
作用
用來(lái)獲取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";
}
屬性
| 屬性 | 說(shuō)明 |
|---|---|
| String value() | 請(qǐng)求參數(shù)中的名稱(chēng), 等同于name |
| boolean required() | 請(qǐng)求參數(shù)中是否必須提供此參數(shù)。默認(rèn)值:true。表示必須提供,如果不提供將報(bào)錯(cuò)。 |
| String defaultValue() | 提供默認(rèn)值 |
栗子
@RestController
public class RequestHeaderController {
@RequestMapping(value="/getHeader")
public String getHeader(
@CookieValue("JSESSIONID") String sessionId){
return "獲取Cookie中的參數(shù)";
}
}
五、@SessionAttributes(了解)
作用
若希望在多個(gè)請(qǐng)求之間共用數(shù)據(jù),則可以在控制器類(lèi)上標(biāo)注一個(gè) @SessionAttributes,配置需要在session中存放的數(shù)據(jù)范圍,Spring MVC將存放在model中對(duì)應(yīng)的數(shù)據(jù)暫存到 HttpSession對(duì)象中
除了可以通過(guò)屬性名指定需要放到會(huì)話中的屬性外,還可以通過(guò)模型屬性的對(duì)象類(lèi)型指定哪些模型屬性需要放到會(huì)話中
源碼
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface SessionAttributes {
@AliasFor("names")
String[] value() default {};
@AliasFor("value")
String[] names() default {};
Class<?>[] types() default {};
}
屬性
| 屬性 | 說(shuō)明 |
|---|---|
| String value() | 請(qǐng)求參數(shù)中的名稱(chēng), 等同于names |
| Class<?>[] types() | 模型屬性的對(duì)象類(lèi)型指定哪些模型屬性需要放到會(huì)話中 |
栗子
配合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) {
// 基本類(lèi)型
model.addAttribute("hello", "world");
// 對(duì)象
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中獲取值";
}
}
// 先訪問(wèn)/session 設(shè)置值
// 在訪問(wèn) /session/attributes 獲取session中的屬性
指定類(lèi)型
@Controller
// value跟type是并集關(guān)系
@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中添加指定類(lèi)型";
}
@RequestMapping("/session/types/get")
@ResponseBody
public User test2(@ModelAttribute("user") User user){
return user
}
}
六、@SessionAttribute(掌握)
作用
引用Session中的某個(gè)屬性, 在某個(gè)方法參數(shù)中,綁定參數(shù),從而在方法中直接使用其值
源碼
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SessionAttribute {
@AliasFor("name")
String value() default "";
@AliasFor("value")
String name() default "";
boolean required() default true;
}
屬性
| 屬性 | 說(shuō)明 |
|---|---|
| String value() | 一個(gè)字符串。里面應(yīng)寫(xiě)需要存儲(chǔ)到session中數(shù)據(jù)的名稱(chēng)。等價(jià)于name |
| boolean required() | 是否必要,請(qǐng)求的session中必須包含該字段 |
栗子
設(shè)置Session數(shù)據(jù)
七、@ModelAttribute(了解)
作用
用在請(qǐng)求方法上,也可以用在參數(shù)上面
- 在方法上,表示當(dāng)前方法會(huì)在控制器的方法執(zhí)行之前,先執(zhí)行。它可以修飾沒(méi)有返回值的方法,也可以修飾有具體返回值的方法。
- 出現(xiàn)在參數(shù)上,獲取指定的數(shù)據(jù)給參數(shù)賦值。
備注
@ModelAttributes 在類(lèi)上使用 - 在類(lèi)上使用的使用修飾的方法在其他方法執(zhí)行前先執(zhí)行。在調(diào)用所有方法之前先執(zhí)行@ModelAttribute標(biāo)記的方法,謹(jǐn)慎使用
應(yīng)用場(chǎng)景
當(dāng)表單提交數(shù)據(jù)不是完整的實(shí)體類(lèi)數(shù)據(jù)時(shí),保證沒(méi)有提交數(shù)據(jù)的字段使用數(shù)據(jù)庫(kù)對(duì)象原來(lái)的數(shù)據(jù)。
源碼
@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;
}
屬性
| 屬性 | 說(shuō)明 |
|---|---|
| String value() | 用于獲取數(shù)據(jù)的 key。key 可以是 POJO 的屬性名稱(chēng),也可以是 map 結(jié)構(gòu)的 key |
栗子
ModelAttribute 無(wú)返回值
@RestController
public class ModelAttributeController {
@ModelAttribute
public void showModel(User user) {
System.out.println("執(zhí)行了 showModel 方法"+user.getName());
}
@RequestMapping("/testModelAttribute")
public String testModelAttribute(User user) {
System.out.println("執(zhí)行了控制器的方法"+user.getName());
return "模型屬性控制";
}
}