中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

spring boot補習系列之幾種scope詳解

發布時間:2020-10-22 13:45:45 來源:腳本之家 閱讀:239 作者:美碼師 欄目:編程語言

目標

  • 了解HTTP 請求/響應頭及常見的屬性;
  • 了解如何使用SpringBoot處理頭信息 ;
  • 了解如何使用SpringBoot處理Cookie ;
  • 學會如何對 Session 進行讀寫;
  • 了解如何在不同請求間傳遞 flash參數

一、Http 頭信息

HTTP 頭(Header)是一種附加內容,獨立于請求內容和響應內容。

HTTP 協議中的大量特性都通過Header信息交互來實現,比如內容編解碼、緩存、連接保活等等。

如下面的一個請求響應:

Request

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: max-age=0
Connection: keep-alive
Host: www.cnblogs.com
If-Modified-Since: Wed, 18 Jul 2018 13:47:45 GMT
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36

名稱 用途
Accept 客戶端期望的MIME 類型列表
Accept-Encoding 客戶端期望的編解碼方式
Accept-Language 客戶端期望的語言
Cache-Control 緩存控制
Connection 連接行為(keep-alive)
Host 請求訪問的主機
If-Modified-Since 緩存控制
Upgrade-Insecure-Requests 支持安全加密標記
User-Agent 用戶代理(客戶端標識)

Response

Cache-Control: private, max-age=10
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Wed, 18 Jul 2018 13:47:51 GMT
Expires: Wed, 18 Jul 2018 13:48:01 GMT
Last-Modified: Wed, 18 Jul 2018 13:47:51 GMT
Transfer-Encoding: chunked
Vary: Accept-Encoding
X-Frame-Options: SAMEORIGIN
X-UA-Compatible: IE=10

名稱 用途
Cache-Control 緩存控制
Connection 連接行為(keep-alive)
Content-Encoding 編解碼方式
Content-Type 內容類型(MIME)
Date 當前響應時間
Expires 文檔過期時間
Last-Modified 最后一次更新時間
Transfer-Encoding 傳輸編碼方式
Vary 需要刷新的請求Header
X-Frame-Options FRAME展示策略(用于同源控制)
X-UA-Compatible IE兼容屬性

更多的** Http Header **可以從這里找到

二、SpringBoot 處理頭信息

前面的內容中已經講過如何完成Controller方法及請求的映射。

在SpringBoot可通過@RequestHeader注解方式

將請求頭信息映射到參數,如下面的片段:

 @GetMapping("/some")
 @ResponseBody
 public String someHeader(@RequestHeader(value = "Host") String host,
  @RequestHeader(value = "User-Agent") String userAgent,
  @RequestHeader(value = "Cache-Control", required = false) String cacheControl,
  HttpServletResponse response) {

 logger.info("host:{}", host);
 logger.info("User-Agent:{}", userAgent);
 logger.info("Cache-Control:{}", cacheControl);

 // 設置響應頭
 response.setHeader("Cache-Control", "no-cache,no-store,must-revalidate");
 response.setHeader("Pragma", "no-cache");
 response.setDateHeader("Expires", 0);
 return "OK";
 }

而響應頭呢,可以通過聲明一個HttpServletResponse參數后,

通過該對象進行設置,上面的代碼非常容易理解。

如果希望獲得全部的請求頭,可以使用HttpHeaders對象:

 @GetMapping("/all")
 public ResponseEntity<Map<String, List<String>>> allHeaders(@RequestHeader HttpHeaders headers) {

 Map<String, List<String>> valueMap = new HashMap<String, List<String>>();
 for (String header : headers.keySet()) {
  valueMap.put(header, headers.get(header));
  logger.info("header[{}]={}", header, headers.get(header));
 }

 // 通過ResponseEntity設置響應頭
 ResponseEntity<Map<String, List<String>>> entity = ResponseEntity.status(HttpStatus.OK)
  .header("new header", UUID.randomUUID().toString()).body(valueMap);
 return entity;
 }

上面的一段代碼中,可以將所有請求頭信息全部打印出來。

此外還須注意到,返回響應使用了ResponseEntity對象,這是一個用于直接表示

響應信息頭、內容的對象,利用ResponseEntity可以很方便的設置響應頭信息。

三、Cookie處理

Cookie一開始服務器用于辨別用戶信息而記錄在瀏覽器上的信息。
到目前為止Cookie作為客戶端的存儲有了非常多的應用場景。

SpringBoot 提供了@CookieValue以支持參數方式注入,如下:

 @GetMapping("/some")
 @ResponseBody
 public String someCookie(@CookieValue(value = "counter", defaultValue = "0") int counter,
  HttpServletResponse response) {

 logger.info("counter:{}", counter);
 counter += 1;

 String newValue = counter + "";

 // 設置Cookie
 response.addCookie(new Cookie("counter", newValue));
 return newValue;
 }

上述代碼中,訪問/some 可以獲得一個counter的cookie值,

且每訪問一次則自增一次,這是一個簡單的訪問計數器功能。

如果希望獲取全部的Cookie,可以參考以下代碼:

 @GetMapping("/all")
 public ResponseEntity<Map<String, String>>allCookies(HttpServletRequest request, HttpServletResponse response) {

 Map<String, String> valueMap = new HashMap<String, String>();
 for (Cookie cookie : request.getCookies()) {

  valueMap.put(cookie.getName(), cookie.getValue());
  logger.info("cookie[{}]={}", cookie.getName(), cookie.getValue());
 }

 // 設置Cookie
 response.addCookie(new Cookie("key", UUID.randomUUID().toString()));
 return new ResponseEntity<Map<String, String>>(valueMap, HttpStatus.OK);
 }

清理全部Cookie

 @GetMapping("/clear")
 public ResponseEntity<Map<String, String>> clearCookies(HttpServletRequest request, HttpServletResponse response) {

 Map<String, String> valueMap = new HashMap<String, String>();
 for (Cookie cookie : request.getCookies()) {

  valueMap.put(cookie.getName(), cookie.getValue());
  logger.info("cookie[{}]={}", cookie.getName(), cookie.getValue());

  // 清除
  cookie.setMaxAge(0);
  response.addCookie(cookie);
 }

 return new ResponseEntity<Map<String, String>>(valueMap, HttpStatus.OK);
 }

Cookie機制存在一定的缺陷,盡可能在考慮一些風險后使用

安全性無法保證,除非使用HTTPS;

瀏覽器端只有4KB大小的存儲上限;

四、Session處理

Session 指的是會話,是建立于Cookie機制上的一種身份識別方式。

由于Cookie自身的安全性和容量限制,大多數應用中是在Cookie中存放一個唯一憑證;

服務側通過憑證再進行身份信息的存取,這就是會話的由來。

不同的語言、框架采用的實現方式有些差異,比如JavaEE采用JSESSION_ID,而PHP則是PHPSESSID

Session的交互原理可以參考下面一個圖:

spring boot補習系列之幾種scope詳解

Springboot 內嵌了Servlet容器,則是沿用的JSESSION_ID。因此在瀏覽一些JavaWeb站點時會發現該Cookie。

使用@SessionAttribute可以將會話中的屬性映射到方法參數;

如果希望對Session屬性進行操作,可以在Controller上聲明@SessionAttributes注解以指定想要變更的屬性;
之后,通過Model參數進行寫入即可(由框架自動檢測并修改Session)

@SessionAttributes("seed")
public class SessionController {

 private static final Logger logger = LoggerFactory.getLogger(SessionController.class);
 @GetMapping("/some")
 @ResponseBody
 public String someSession(@SessionAttribute(value = "seed", required = false) Integer seed, Model model) {

  logger.info("seed:{}", seed);
  if (seed == null) {
   seed = (int) (Math.random() * 10000);
  } else {
   seed += 1;
  }
  model.addAttribute("seed", seed);

  return seed + "";
 }

上面的例子與Cookie實現訪問計數器的功能是一樣的!

如果希望獲取全部會話,可以使用HttpSession

 @GetMapping("/all")
 public ResponseEntity<Map<String, Object>> allSessions(HttpSession session) {

  Map<String, Object> valueMap = new HashMap<String, Object>();
  Enumeration<String> iSession = session.getAttributeNames();

  while (iSession.hasMoreElements()) {
   String sessionName = iSession.nextElement();
   Object sessionValue = session.getAttribute(sessionName);

   valueMap.put(sessionName, sessionValue);
   logger.info("sessoin[{}]={}", sessionName, sessionValue);
  }

  // 寫入session
  session.setAttribute("timestmap", new Date());
  return new ResponseEntity<Map<String, Object>>(valueMap, HttpStatus.OK);
 }

清除會話

 @GetMapping("/clear")
 public ResponseEntity<Map<String, Object>> clearSessions(HttpSession session) {

  Map<String, Object> valueMap = new HashMap<String, Object>();
  Enumeration<String> iSession = session.getAttributeNames();

  while (iSession.hasMoreElements()) {
   String sessionName = iSession.nextElement();
   Object sessionValue = session.getAttribute(sessionName);

   valueMap.put(sessionName, sessionValue);
   logger.info("sessoin[{}]={}", sessionName, sessionValue);
   
   session.removeAttribute(sessionName);
  }
  
  return new ResponseEntity<Map<String, Object>>(valueMap, HttpStatus.OK);
 }

五、Flash參數傳遞

Flash的意思是一瞬間,一閃而過的,因此很好理解,這是一類僅用來消費一次的參數,有些類似閱后即焚。
試想這樣的場景,你確認完購物車,完成訂單支付后進入訂單管理界面,而此時界面上提示你"下單成功,請等待發貨"。
這便可以通過Flash傳參來實現。

Flash的意義是用作請求之間的瞬時參數傳遞,僅消費一次后便不再用。

以下是一個示例:

 /**
  * 執行跳轉,并設置傳值
  *
  * @param counter
  * @param response
  * @return
  */
 @GetMapping("/first")
 public String first(final RedirectAttributes redirectAttrs) {

  logger.info("redirect start:{}");

  redirectAttrs.addFlashAttribute("flash", UUID.randomUUID().toString());
  return "redirect:/flash/second";
 }

 /**
  * 獲取傳值
  * 
  * @param session
  * @param response
  * @return
  */
 @GetMapping("/second")
 @ResponseBody
 public String second(@ModelAttribute("flash") String flash) {

  logger.info("redirect receive {}", flash);
  return flash;
 }

交互原理

spring boot補習系列之幾種scope詳解

Sprintboot中Flash機制也是利用Session實現的,其中FlashMapManager接口實現了Flash參數的管理。

默認的實現是SessionFlashMapManager,可以通過RequestContextUtils獲得上下文中的FlashMapManager對象。

RequestContextUtils通過Request Scope(請求上下文)存取對象

這也是一個本文未提及的scope域,Request上下文是利用線程變量實現的,通常用于線程內業務處理的數據交互。

小結

HTTP 頭信息是一種附加內容,用于實現HTTP協議中的各種特性,在開始部分介紹了常見的頭信息定義。

本文主要介紹了幾種常見的HTTP scope信息的存取方法,包括如何對header、cookie進行讀取及修改。

springboot 內嵌了Servlet容器,會話處理機制上沿用了JSESSIONID,通過代碼示例介紹了會話的處理方法;

Flash參數是一種閱后即焚的數據,其底層實現也用了session的實現方案。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

晋宁县| 碌曲县| 长寿区| 珲春市| 建阳市| 鸡西市| 衡水市| 承德县| 大厂| 龙里县| 锡林郭勒盟| 阜康市| 新野县| 清河县| 西林县| 陵水| 翁源县| 囊谦县| 东台市| 湘乡市| 年辖:市辖区| 麻江县| 宁蒗| 龙井市| 婺源县| 十堰市| 马山县| 醴陵市| 靖宇县| 读书| 通州区| 察隅县| 富民县| 郎溪县| 屯留县| 乃东县| 灵宝市| 高清| 婺源县| 新营市| 德清县|