javascript
转:Spring Boot 获取 HttpServletRequest 的方法
轉自:
Spring Boot 獲取 HttpServletRequest 的方法 - 簡書本文介紹 Spring Boot 2 獲取 HttpServletRequest 的方法。 目錄 概述 方法Controller 方法參數(shù)屬性自動注入手動方法調用借助 @Mo...https://www.jianshu.com/p/b7a7d66c4ef2
本文介紹 Spring Boot 2 獲取 HttpServletRequest 的方法。
目錄
- 概述
- 方法
- Controller 方法參數(shù)
- 屬性自動注入
- 手動方法調用
- 借助 @ModelAttribute 注解
- 總結
概述
借助 Spring MVC 開發(fā) Web 應用的過程中經常需要使用 HttpServletRequest 對象獲取 HTTP 請求相關的信息,如:客戶端 IP、HTTP Header 中的屬性等。
使用 HttpServletRequest 對象的場景大體分為兩類:
- 在 Spring 注入的 Bean 中使用;
- 在非 Spring 注入的 Bean 中使用,如普通的 Java 對象或類的靜態(tài)方法。
方法
【1】Controller 方法參數(shù)引入 HttpServletRequest
原理:
在 Controller 方法開始處理請求時,Spring 會將 HttpServletRequest 對象自動賦值到方法參數(shù)中。除 HttpServletRequest 對象外,還有很多其它參數(shù)可以通過此方法獲取,參考:https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-ann-methods
代碼示例:
@GetMapping("/method1") public String method1(HttpServletRequest request) {System.out.println("Request URI: " + request.getRequestURI());return "Invoke HttpServletRequest by method param."; }線程安全性分析:
HttpServletRequest 對象作為方法參數(shù),相當于局部變量,是 線程安全 的。
缺點:
- 代碼冗余,每個 Controller 方法中都要有 HttpServletRequest request 參數(shù);
- HttpServletRequest 對象的獲取必須從 Controller 開始,如果使用 HttpServletRequest 對象的地方在函數(shù)調用層級比較深的地方,那么整個函數(shù)調用鏈上的所有方法都要有 HttpServletRequest request 參數(shù)。實際上在請求處理的全過程中,HttpServletRequest 對象始終存在,相當于線程內部的一個全局變量。
【2】HttpServletRequest 屬性自動注入
代碼示例:
@Autowired private HttpServletRequest autowiredRequest;@GetMapping("/method2") public String method2() {System.out.println("Request URI: " + autowiredRequest.getRequestURI());return "Invoke HttpServletRequest by @Autowired."; }線程安全性分析:
使用 @Autowired 注解時,Spring 實際注入的并非 HttpServletRequest 對象,而是一個代理 proxy(代理實現(xiàn)參考 AutowireUtils.ObjectFactoryDelegatingInvocationHandler),當方法中需要使用 HttpServletRequest 對象時通過此代理獲取,所以雖然 Controller 是個單例類,但通過此方法使用 HttpServletRequest 對象是 線程安全 的。
優(yōu)點:
- 不局限于 Controller 中,可以在通過 @Component、@Service、@Repository 注解注入的其它 Bean 中使用;
- 注入的對象不局限于 HttpServletRequest 對象,還可以注入其它 scope 為 request 或 session 的對象,如 HttpServletResponse、HttpSession 等,并保證線程安全;
- 相比于【Controller 方法參數(shù)】方法,減少了代碼冗余,只需要在需要使用 HttpServletRequest 對象的方法所屬 Bean 中注入。
缺點:
- 如果存在很多 Bean 需要使用 HttpServletRequest 對象,則每個 Bean 都要維護一個使用 @Autowired 注解注入的 HttpServletRequest request 屬性,也存在一定代碼冗余,可以定義一個公共父類維護這些自動注入的屬性,但是繼承本身也存在一定問題。
【3】手動方法調用
代碼示例:
@GetMapping("/method3") public String method3() {HttpServletRequest request =((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();System.out.println("Request URI: " + request.getRequestURI());return "Invoke HttpServletRequest by ServletRequestAttributes."; }線程安全性分析:
與【屬性自動注入】線程安全性分析一致,屬于 線程安全。
優(yōu)點:
- 可以在非 Spring 注入的 Bean 中使用,如普通 Java 對象或靜態(tài)方法。
缺點:
- 代碼比較繁瑣。
【4】借助 @ModelAttribute 注解
代碼示例:
@Autowired private HttpServletRequest bindRequest;@ModelAttribute public void bindRequest(HttpServletRequest request) {this.bindRequest = request; }@GetMapping("/method4") public String method4() {System.out.println("Request URI: " + bindRequest.getRequestURI());return "Invoke HttpServletRequest by @ModelAttribute."; }線程安全性分析:
@ModelAttribute 注解修飾 Controller 方法時,作用是在 Controller 中每個處理請求的方法執(zhí)行前執(zhí)行,而 Controller 是單例,所以當同時處理多個請求時 HttpServletRequest 對象屬性可能會被覆蓋,所以是 線程不安全 的!
總結
全量代碼:
package tutorial.spring.boot.mvc.controller;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;@RestController public class DemoController {@Autowiredprivate HttpServletRequest autowiredRequest;@Autowiredprivate HttpServletRequest bindRequest;@GetMapping("/method1")public String method1(HttpServletRequest request) {System.out.println("Request URI: " + request.getRequestURI());return "Invoke HttpServletRequest by method param.";}@GetMapping("/method2")public String method2() {System.out.println("Request URI: " + autowiredRequest.getRequestURI());return "Invoke HttpServletRequest by @Autowired.";}@GetMapping("/method3")public String method3() {HttpServletRequest request =((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();System.out.println("Request URI: " + request.getRequestURI());return "Invoke HttpServletRequest by ServletRequestAttributes.";}@ModelAttributepublic void bindRequest(HttpServletRequest request) {this.bindRequest = request;}@GetMapping("/method4")public String method4() {System.out.println("Request URI: " + bindRequest.getRequestURI());return "Invoke HttpServletRequest by @ModelAttribute.";} }
?
總結
以上是生活随笔為你收集整理的转:Spring Boot 获取 HttpServletRequest 的方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小米电视4c能不能有手机连接电脑上网(小
- 下一篇: 织梦怎么套用模板(什么是织梦模板)