Cookie壓縮

在介紹cookie壓縮之前先來(lái)介紹一下cookie保存中文,因?yàn)樵趬嚎scookie時(shí)要將結(jié)果進(jìn)行轉(zhuǎn)碼好像就是這個(gè)原因
原本以為cookie保存中文,頂多在取值時(shí)會(huì)出現(xiàn)亂碼,然而并不是這樣的,寫(xiě)了個(gè)測(cè)試demo
TestEncode.java

public class TestEncode extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie[] cookies = req.getCookies();

        for (Cookie c : cookies) {
            System.out.println(c.getName());
        }
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie c = new Cookie("姓名", "皮皮甜");
        resp.addCookie(c);
        doPost(req, resp);
    }
}

在web.xml進(jìn)行了url映射配置,然后,做測(cè)試就報(bào)錯(cuò)了

HTTP Status 500 - Cookie name "姓名" is a reserved token
type Exception report

message Cookie name "姓名" is a reserved token

description The server encountered an internal error that prevented it from fulfilling this request.

exception

java.lang.IllegalArgumentException: Cookie name "姓名" is a reserved token
    javax.servlet.http.CookieNameValidator.validate(Cookie.java:406)
    javax.servlet.http.Cookie.<init>(Cookie.java:120)
    com.cqupt.javaweb.TestEncode.doGet(TestEncode.java:26)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:622)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    com.cqupt.javaweb.EncodingFilter.doFilter(EncodingFilter.java:29)
note The full stack trace of the root cause is available in the Apache Tomcat/8.0.30 logs.

中文果然不可以,因?yàn)橹形牡木幋a方式是Unicode。在servlet中創(chuàng)建Cookie必須遵守RFC 2109規(guī)范。RFC 2019規(guī)范里面就是key,value必須是ascii字符,或base64。將key和value換成英文以后就成功了,但是如果非要使用中文,也是有方法可以做到的。
Cookie中使用Unicode字符時(shí)需要對(duì)Unicode字符進(jìn)行編碼,編碼可以使用URLEncoder類(lèi)的encode(String str, String encoding)方法,解碼使用URLDecoder類(lèi)的decode(String str, String encoding)方法。
哪里失敗就從哪里爬起,繼續(xù)改代碼

public class TestEncode extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie[] cookies = req.getCookies();

        for (Cookie c : cookies) {
            String cookieName = URLDecoder.decode(c.getName(), "gbk");
            String cookieValue = URLDecoder.decode(c.getValue(), "gbk");
            System.out.println(cookieName + " : " + cookieValue);
        }
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Cookie c = new Cookie(URLEncoder.encode("姓名"), URLEncoder.encode("皮皮甜"));
        resp.addCookie(c);
//        resp.setCharacterEncoding("UTF-8");
        doPost(req, resp);
    }
}

程序運(yùn)行結(jié)果:

姓名 : 皮皮甜

現(xiàn)在進(jìn)入cookie壓縮壓縮介紹
為什么需要進(jìn)行cookie壓縮,因?yàn)閏ookie是保存在http的頭部的,服務(wù)器和客戶端進(jìn)行交互時(shí),需要進(jìn)行cookie傳輸,如果cookie數(shù)量非常多、并且內(nèi)容特別多的時(shí)候,無(wú)形增大了數(shù)據(jù)傳輸量,會(huì)占用很大的網(wǎng)絡(luò)帶寬。進(jìn)行壓縮,可以減少數(shù)據(jù)量。
cookie壓縮:將cookie的多個(gè)k/v對(duì)看成普通的文本,做文本壓縮。壓縮算法可以使用gzip和deflate算法,因?yàn)閏ookie規(guī)范中,cookie中不能包含控制字符(壓縮以后會(huì)出現(xiàn)==這些控制字符串),所以需要對(duì)壓縮后的結(jié)果進(jìn)行轉(zhuǎn)碼,可以使用Base32或者Base64。
因?yàn)槭褂肂ase64進(jìn)行編碼的時(shí)候會(huì)出現(xiàn)一些問(wèn)題,所以選擇了URLEncode進(jìn)行了編碼

demo:在向客戶端發(fā)送cookie時(shí)就進(jìn)行壓縮
 /**
     * 服務(wù)器向客戶端頒發(fā)cookie,在頒發(fā)給客戶端時(shí)先對(duì)cookie進(jìn)行壓縮
     * @param response
     * @param name cookie名字
     * @param value cookie值
     * @throws IOException
     * */
    public static void addCookie(HttpServletResponse response, String name, String value) throws IOException {
        System.out.println("進(jìn)入了方法體...");


        //進(jìn)行cookie進(jìn)行壓縮
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        DeflaterOutputStream dos = new DeflaterOutputStream(bos);

        dos.write(name.getBytes());
        dos.close();
        System.out.println("name: " + name);
        System.out.println("name before compress length: " + name.length());
        String compressName = URLEncoder.encode(new String(bos.toByteArray()), "UTF-8");
//        String compressName = new BASE64Encoder().encode(bos.toByteArray());
        System.out.println("name after compress length: " + compressName.length());
        System.out.println("compressName: " + compressName);

        ByteArrayOutputStream bos1 = new ByteArrayOutputStream();
        DeflaterOutputStream dos1 = new DeflaterOutputStream(bos1);

        dos1.write(value.getBytes());
        dos1.close();
        System.out.println("value: " + value);
        System.out.println("value before compress length: " + value.length());
        //壓縮以后進(jìn)行編碼
        String compressValue = URLEncoder.encode(new String(bos.toByteArray()), "UTF-8");
        System.out.println("value after compress length: " + compressValue.length());
        System.out.println("compressValue: " + compressValue);

        //壓縮以后需要使用使用base64進(jìn)行編碼,因?yàn)閴嚎s以后存在控制字符,不符合cookie標(biāo)準(zhǔn)
    //        String lastName = URLEncoder.encode(compressName, "UTF-8");
    //        String lastValue = URLEncoder.encode(compressValue, "UTF-8");
    //        System.out.println("lastName: " + lastName);
    //        System.out.println("lastValue: " + lastValue);

        Cookie cookie = new Cookie(compressName, compressValue);
        cookie.setPath("/");  //本域名下contextPath都可以訪問(wèn)該Cookie

        cookie.setMaxAge(Integer.MAX_VALUE);  //失永遠(yuǎn)保存在瀏覽器,除非人為進(jìn)行清理
        System.out.println("發(fā)送結(jié)束...");
        unCompressCookie(cookie);
        response.addCookie(cookie);  //向客戶端發(fā)送cookie
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,973評(píng)論 19 139
  • 編碼問(wèn)題一直困擾著開(kāi)發(fā)人員,尤其在 Java 中更加明顯,因?yàn)?Java 是跨平臺(tái)語(yǔ)言,不同平臺(tái)之間編碼之間的切換...
    x360閱讀 2,515評(píng)論 1 20
  • 歲月如歌,歡快而悠遠(yuǎn),往事如酒,醇厚而纏綿。塵封的記憶,三十年,像洪水,突然決堤,竟在不經(jīng)意間。 秋天來(lái)了,你也來(lái)...
    教育的天空閱讀 503評(píng)論 0 1
  • 九月份,姑娘去了東陽(yáng)求學(xué)。空間有了距離后,思念在發(fā)酵,愛(ài)就沉淀著。 第一次姑娘回家時(shí),向來(lái)不買(mǎi)菜的爸爸在網(wǎng)上訂了兩...
    JC賈閱讀 257評(píng)論 1 2
  • 分答活動(dòng):生命分答——如果生命只剩最后60秒你想對(duì)這個(gè)世界說(shuō)說(shuō)什么? 活動(dòng)說(shuō)明在生命最后60秒,你會(huì)想對(duì)這個(gè)世界說(shuō)...
    神域熊貓閱讀 278評(píng)論 0 1