優質專案原始碼推薦
SpringBoot + Vue + MyBatis 音樂網站專案
【超高顏值】一款高顏值的 SpringBoot+JPA 博客專案
推薦一款 SpringBoot 私活腳手架,開發效率可提高 70%
Java 私活神器,一套 SpringBoot+Vue 通用的后臺管理系統
SpringCloud 網上商城系統(附原始碼及教程)
大家好,我是路人,這是 SpringMVC 系列第 27 篇,
本文將介紹 SpringMVC 中的@RequestAttribute 注解,
1、預備知識
介面測驗利器 HTTP Client
引數決議器 HandlerMethodArgumentResolver 解密
2、@RequestAttribute 注解
2.1、作用
用來標注在介面的引數上,引數的值來源于 request 作用域,
2.2、用法
如下代碼,site 引數上使用了@RequestAttribute("site")注解,site 引數的值等于request.getAttribute("site")
@ResponseBody
public String test2(@RequestAttribute("site") String site) {
return site;
}
這個注解的原始碼如下
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestAttribute {
/**
* 指定request作用域中屬性的名稱
*/
@AliasFor("name")
String value() default "";
/**
* 同value屬性
*/
@AliasFor("value")
String name() default "";
/**
* 屬性是不是必須的,如果是true,request中沒有取到時,則會拋出例外
* 此時可以將required設定為false,或者使用java8中的Option型別來修飾引數解決
*/
boolean required() default true;
}
3、案例
下面代碼中有 2 個介面方法
第一個方法 test1 中向 request 域中丟了一個 site 屬性,然后進行了跳轉,跳轉到第二個方法,最后將 site 作為回應體輸出
第二個方的 site 引數上標注了
@RequestAttribute("site"),所以會拿到 request 中 site 的值,然后輸出
package com.javacode2018.springmvc.chat18.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
@Controller
public class RequestAttributeController {
@RequestMapping("/requestattribute/test1")
public String test1(HttpServletRequest request) {
request.setAttribute("site",
"<a href='http://www.itsoku.com'>路人博客,包含了所有系列文章,閱讀更方便</a>");
return "forward:/requestattribute/test2";
}
@RequestMapping(value = "/requestattribute/test2", produces = "text/html;charset=UTF-8")
@ResponseBody
public String test2(@RequestAttribute("site") String site) {
return site;
}
}
瀏覽器中訪問第一個介面/requestattribute/test1,輸出如下

若我們調整一下介面 1 中代碼,將 site 的值置為空
request.setAttribute("site", null);
此時再次訪問介面會報 400 錯誤,原因:request 域中沒有找到 site 這個屬性對應的值,即 request.getAttribute("site")為 null

2 種解決方案
方案 1:將@RequestAttribute 的 required 屬性設定為 false,常用這種方式
方案 2:將@RequestAttribute 標注的引數型別調整為 java8 中的 java.util.Optional 型別,上面的介面 2 的 site 引數型別可以調整為
Optional<String>型別,即可解決問題
4、@RequestAttribute 注解原理
@RequestAttribute 注解標注的引數的值來源于org.springframework.web.servlet.mvc.method.annotation.RequestAttributeMethodArgumentResolver決議器,原始碼
public class RequestAttributeMethodArgumentResolver extends AbstractNamedValueMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(RequestAttribute.class);
}
@Override
protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
RequestAttribute ann = parameter.getParameterAnnotation(RequestAttribute.class);
Assert.state(ann != null, "No RequestAttribute annotation");
return new NamedValueInfo(ann.name(), ann.required(), ValueConstants.DEFAULT_NONE);
}
@Override
@Nullable
protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest request){
return request.getAttribute(name, RequestAttributes.SCOPE_REQUEST);
}
@Override
protected void handleMissingValue(String name, MethodParameter parameter) throws ServletException {
throw new ServletRequestBindingException("Missing request attribute '" + name +
"' of type " + parameter.getNestedParameterType().getSimpleName());
}
}
5、案例代碼 git 地址
https://gitee.com/javacode2018/springmvc-series
所有系列文章的均在此倉庫中,
6、SpringMVC 系列目錄
SpringMVC 系列第 1 篇:helloword
SpringMVC 系列第 2 篇:@Controller、@RequestMapping
SpringMVC 系列第 3 篇:例外高效的一款介面測驗利器
SpringMVC 系列第 4 篇:controller 常見的接收引數的方式
SpringMVC 系列第 5 篇:@RequestBody 大解密,說點你不知道的
SpringMVC 系列第 6 篇:上傳檔案的 4 種方式,你都會么?
SpringMVC 系列第 7 篇:SpringMVC 回傳視圖常見的 5 種方式,你會幾種?
SpringMVC 系列第 8 篇:回傳 json & 通用回傳值設計
SpringMVC 系列第 9 篇:SpringMVC 回傳 null 是什么意思?
SpringMVC 系列第 10 篇:異步處理
SpringMVC 系列第 11 篇:集成靜態資源
SpringMVC 系列第 12 篇:攔截器
SpringMVC 系列第 13 篇:統一例外處理
SpringMVC 系列第 14 篇:實戰篇:通用回傳值 & 例外處理設計
SpringMVC 系列第 15 篇:全注解的方式 & 原理決議
SpringMVC 系列第 16 篇:通過原始碼決議 SpringMVC 處理請求的流程
SpringMVC 系列第 17 篇:原始碼決議 SpringMVC 容器的啟動程序
SpringMVC 系列第 18 篇:強大的 RequestBodyAdvice 解密
SpringMVC 系列第 19 篇:強大的 ResponseBodyAdvice 解密
SpringMVC 系列第 20 篇:RestFull 詳解
SpringMVC 系列第 21 篇:介面呼叫過利器 RestTemplate
SpringMVC 系列第 22 篇:引數決議器 HandlerMethodArgumentResolver 解密
SpringMVC 系列第 23 篇:@RequestParam 用法及原理詳解
SpringMVC 系列第 24 篇:@RequestBody 用法及原理詳解
SpringMVC 系列第 25 篇:@RequestHeader 用法及原理詳解
SpringMVC 系列第 26 篇:@CookieValue 用法及原理詳解
7、更多系列文章
Spring 高手系列(共 56 篇)
Java 高并發系列(共 34 篇)
MySql 高手系列(共 27 篇)
Maven 高手系列(共 10 篇)
Mybatis 系列(共 12 篇)
聊聊 db 和快取一致性常見的實作方式
介面冪等性這么重要,它是什么?怎么實作?
泛型,有點難度,會讓很多人懵逼,那是因為你沒有看這篇文章!
8、最新資料
尚硅谷 Java 學科全套教程(總 207.77GB)
2021 最新版 Java 微服務學習線路圖 + 視頻
阿里技術大佬整理的《Spring 學習筆記.pdf》
阿里大佬的《MySQL 學習筆記高清.pdf》
2021 版 java 高并發常見面試題匯總.pdf
Idea 快捷鍵大全.pdf
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/396547.html
標籤:其他
上一篇:spring boot task實作動態創建定時任務
下一篇:Java習題(八)
