WebFlux讀寫Cookie不像WebMvc那麼直接,最主要的緣由是WebMvc是基於Servlet規範的,而WebFlux僅僅遵照的是HTTP協議。因此在使用的時候會發現HttpServletRequest
、HttpServletResponse
這些Servlet層級的接口根本就沒法使用。前端
Cookie與Servlet並無太直接的關係,前者是屬於HTTP規範的然後者是一個J2EE的規範,在應用層面僅有的聯繫就是Servlet會讀寫Cookie中的JSESSIONID來標記與前端瀏覽器和服務端的關係。而HttpServletRequest
、HttpServletResponse
僅是Servlet爲請求和響應提供header、body管理的接口。瀏覽器
WebFlux目前並無爲寫Cookie提供任何工具。這就須要開發者按照HTTP的規範來寫Cookie。 在HTTP協議交互的過程當中,服務端能夠經過在response中添加Set-Cookie頭來讓瀏覽器記錄Cookie,而瀏覽器則在request中使用Cookie頭來傳遞cookie。cookie
寫cookie使用ResponseEntity
向response頭中添加Set-Cookie便可。CookieBuilder
的代碼比較長,它是用於構建一個cookie字符串,Set-Cookie頭除了設置key=value,還能夠設置過時日期expires,域名domain,路徑path等。app
@RestController @RequestMapping("/cookie") public class CookieReadAWriteController { @GetMapping("/write") public ResponseEntity<String> cookieWrite() { HttpHeaders headers = new HttpHeaders(); String cookie = new CookieBuilder().setKey("cookie-text") .setValue(cookieText) .setMaxAge(840000) .setPath("/") .build(); headers.add("Set-Cookie", cookie); return new ResponseEntity<String>("hi," + userName, headers, HttpStatus.OK); } } class CookieBuilder { private String key; private String value; private String expires; private String domain; private String path; public CookieBuilder setKey(String key) { this.key = key; return this; } public CookieBuilder setValue(String value) { this.value = value; return this; } public CookieBuilder setMaxAge(long ms) { //cookie的過時日期爲GMT格式的時間。 Date date = new Date(new Date().getTime() + ms); SimpleDateFormat sdf = new SimpleDateFormat("EEE d MMM yyyy HH:mm:ss 'GMT'", Locale.US); sdf.setTimeZone(TimeZone.getTimeZone("GMT")); this.expires = sdf.format(date); return this; } public CookieBuilder setDomain(String domain) { this.domain = domain; return this; } public CookieBuilder setPath(String path) { this.path = path; return this; } public String build() { StringBuilder sb = new StringBuilder(); sb.append(this.key); sb.append("="); sb.append(this.value); sb.append(";"); if (null != this.expires) { sb.append("expires="); sb.append(this.expires); sb.append(";"); } if (null != this.domain) { sb.append("domain="); sb.append(this.domain); sb.append(";"); } if (null != this.path) { sb.append("path="); sb.append(this.path); sb.append(";"); } return sb.toString(); } }
獲取cookie就比較直觀,能夠直接使用@CookieValue
這個Annotation來獲取:dom
@RestController @RequestMapping("/cookie") public class CookieReadAWriteController { @GetMapping("/read/annotation") /** * @param value * @return */ public String cookieReadAnnotation(@CookieValue("cookie-text") String value) { return "當前Cookie中的內容" + value; } }
也能夠直接從Request的Header中獲取:工具
@RestController @RequestMapping("/cookie") public class CookieReadAWriteController { @GetMapping("/read/annotation") /** * @param value * @return */ @GetMapping("/read/entity") public String cookieReadEntity(RequestEntity<String> entity) { HttpHeaders headers = entity.getHeaders(); List<String> cookie = headers.get("Cookie"); return "當前Cookie中的內容" + cookie; } }
使用Annotatin是直接標記Cookie的key來獲取value。而使用RequestEntity須要從頭中先獲取Cookie的內容,而後再解析key和value,存在一個key對應多個value的狀況須要使用RequestEntity。ui
原文連接:https://my.oschina.net/chkui/blog/2993002this