問題描述:
使用springMVC的時候,有些時候會需要獲取請求或者響應對象,例如在身份驗證的時候,需要獲取請求頭中的token,在做登錄系統的時候需要使用response對象向客戶端添加cookie,一個有效的做法是在controller的方法中添加對應參數如下所示:
1 @RestController 2 public class Test2Contrller { 3 @RequestMapping("/test") 4 public void test(HttpServletRequest req, HttpServletResponse res) { 5 // todo 6 } 7 }
這樣做有一個問題,就是如果這個系統是作為接口並希望被遠程調用的,那么額外的參數的存在便會破壞原本的接口定義,造成麻煩,下面介紹兩種不需要在方法中增加額外參數就能獲取request和response的方式
第一種方式:通過RequestContextHolder類的方法獲取requestAttributes,再從中獲取請求和響應對象;
1 @RestController 2 public class Test2Contrller { 3 @RequestMapping("/testreq") 4 public void test() { 5 // 獲得request對象,response對象 6 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); 7 HttpServletRequest request = attributes.getRequest(); 8 HttpServletResponse response = attributes.getResponse(); 9 try { 10 response.getWriter().write("hello"); 11 } catch (IOException e) { 12 e.printStackTrace(); 13 } 14 Enumeration<String> headerNames = request.getHeaderNames(); 15 while (headerNames.hasMoreElements()) { 16 String name = headerNames.nextElement(); 17 String value = request.getHeader(name); 18 System.out.println(name + "===========" + value); 19 } 20 21 } 22 }
第二種方式:可以將請求和響應對象抽取出來放在一個超類中,需要使用這兩個對象的controller繼承這個類,直接使用即可,代碼如下:
超類:
1 public class BaseController { 2 // 這些對象何以直接被子類使用 3 protected HttpServletRequest request; 4 protected HttpServletResponse response; 5 protected HttpSession session; 6 7 @ModelAttribute 8 public void setReqAndRes(HttpServletRequest req, HttpServletResponse res) { 9 this.request = req; 10 this.response = res; 11 this.session = req.getSession(); 12 } 13 }
子類:
1 @RestController 2 public class Test3Contrller extends BaseController{ 3 @RequestMapping("/testreq2") 4 public void test() { 5 try { 6 response.getWriter().write("hello"); 7 } catch (IOException e) { 8 e.printStackTrace(); 9 } 10 Enumeration<String> headerNames = request.getHeaderNames(); 11 while (headerNames.hasMoreElements()) { 12 String name = headerNames.nextElement(); 13 String value = request.getHeader(name); 14 System.out.println(name + "===========" + value); 15 } 16 17 } 18 }
可以看到第二種方式代碼簡潔很多,如果對請求或者響應對象有大量的使用需求,例如需要從傳過來的請求頭中的token獲取用戶信息,動態的返回結果時,建議使用第二種方式;
博客地址:https://blog.csdn.net/xiang__liu,https://www.cnblogs.com/xiang--liu/