Spinrg WebFlux中Cookie的讀寫

WebFLux與WebMvc的差別

WebFlux讀寫Cookie不像WebMvc那麼直接,最主要的緣由是WebMvc是基於Servlet規範的,而WebFlux僅僅遵照的是HTTP協議。因此在使用的時候會發現HttpServletRequestHttpServletResponse這些Servlet層級的接口根本就沒法使用。前端

CookieServlet並無太直接的關係,前者是屬於HTTP規範的然後者是一個J2EE的規範,在應用層面僅有的聯繫就是Servlet會讀寫Cookie中的JSESSIONID來標記與前端瀏覽器和服務端的關係。而HttpServletRequestHttpServletResponse僅是Servlet爲請求和響應提供headerbody管理的接口。瀏覽器

WebFlux的Cookie管理

WebFlux目前並無爲寫Cookie提供任何工具。這就須要開發者按照HTTP的規範來寫Cookie。 在HTTP協議交互的過程當中,服務端能夠經過在response中添加Set-Cookie頭來讓瀏覽器記錄Cookie,而瀏覽器則在request中使用Cookie頭來傳遞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

獲取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是直接標記Cookiekey來獲取value。而使用RequestEntity須要從頭中先獲取Cookie的內容,而後再解析keyvalue,存在一個key對應多個value的狀況須要使用RequestEntityui

原文連接:https://my.oschina.net/chkui/blog/2993002this

相關文章
相關標籤/搜索