HttpURLConnection 中Cookie 使用

如果想通过 HttpURLConnection 访问网站,网站返回cookie信息,下次再通过HttpURLConnection访问时,把网站返回 cookie信息再返回给该网站。可以使用下面代码。

CookieManager manager = new CookieManager();
CookieHandler.setDefault(manager);

通过这两行代码就可以把网站返回的cookie信息存储起来,下次访问网站的时候,自动帮你把cookie信息带上。

CookieManager还可以设置CookiePolicy。设置如下:

CookieManager manager = new CookieManager();
//设置cookie策略,只接受与你对话服务器的cookie,而不接收Internet上其它服务器发送的cookie
manager.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER);

有关CookiePolicy请详看: CookiePolicy 原理解析

CookieHandler 源码分析

public abstract class CookieHandler {

    private static CookieHandler cookieHandler;

    public synchronized static CookieHandler getDefault() {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(SecurityConstants.GET_COOKIEHANDLER_PERMISSION);
        }
        return cookieHandler;
    }
   
    public synchronized static void setDefault(CookieHandler cHandler) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(SecurityConstants.SET_COOKIEHANDLER_PERMISSION);
        }
        cookieHandler = cHandler;
    }
    
    public abstract Map<String, List<String>>
        get(URI uri, Map<String, List<String>> requestHeaders)
        throws IOException;

    public abstract void
        put(URI uri, Map<String, List<String>> responseHeaders)
        throws IOException;
}

CookieHandler是抽象类,内部提供了静态的setDefault方法。 并且 private static CookieHandler cookieHandler; 是静态的。 子类需要实现get()和put()方法。 get()方法返回该uri相关的cookie。 put()方法是存储该uri相关的cookie。

jdk1.6中提供了CookieHandler的实现类CookieManager。

CookieManager 源码分析

get()方法

Paste_Image.png

CookieManager.get() 方法实现了从CookieStore中获取该uri对应的cookie。

put() 方法

Paste_Image.png

首先解析http 相应头信息中的cookie,并存储到 List<HttpCookie> cookies 中。

Paste_Image.png

循环cookies中的cookie,根据设置的CookiePolicy来判断是否接收该Cookie信息, 如果接收则存储到CookieStore。

Cookie实现机制

这样每次在调用HttpURLConnection访问网站的时候,通过CookieHandler.getDefault()方法获取CookieManager实例(静态的方法,全局都可用)。 从解析http的响应头中的cookie调用CookieHandler中的put方法存放到CookieStore中。 再次访问网站的时候调用CookieHandler中的get方法获取该uri响应的cookie,并提交到该站点中。 这样开发人员就不需要干预cookie信息,则每次访问网站会自动携带cookie。

代码示例

本例子中使用到了CookieHandler、CookieManager 、CookieStore、 HttpCookie。

public class CookieManagerDemo {

    //打印cookie信息
    public static void printCookie(CookieStore cookieStore){
        List<HttpCookie> listCookie = cookieStore.getCookies();
        listCookie.forEach(httpCookie -> {
            System.out.println("--------------------------------------");
            System.out.println("class      : "+httpCookie.getClass());
            System.out.println("comment    : "+httpCookie.getComment());
            System.out.println("commentURL : "+httpCookie.getCommentURL());
            System.out.println("discard    : "+httpCookie.getDiscard());
            System.out.println("domain     : "+httpCookie.getDomain());
            System.out.println("maxAge     : "+httpCookie.getMaxAge());
            System.out.println("name       : "+httpCookie.getName());
            System.out.println("path       : "+httpCookie.getPath());
            System.out.println("portlist   : "+httpCookie.getPortlist());
            System.out.println("secure     : "+httpCookie.getSecure());
            System.out.println("value      : "+httpCookie.getValue());
            System.out.println("version    : "+httpCookie.getVersion());
            System.out.println("httpCookie : "+httpCookie);
        });
    }

    public static void requestURL() throws Exception{
        URL url = new URL("http://192.168.3.249:9000/webDemo/index.jsp");
        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
        String basic = Base64.getEncoder().encodeToString("infcn:123456".getBytes());
        conn.setRequestProperty("Proxy-authorization", "Basic " + basic);
        BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String line = null;
        while((line=br.readLine())!=null){
            System.out.println(line);
        }
        br.close();
    }

    public static void main(String[] args) throws Exception {
        
        CookieManager manager = new CookieManager();
        //设置cookie策略,只接受与你对话服务器的cookie,而不接收Internet上其它服务器发送的cookie
        manager.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER);
        CookieHandler.setDefault(manager);
        
        printCookie(manager.getCookieStore());
        //第一次请求
        requestURL();

        printCookie(manager.getCookieStore());
        //第二次请求
        requestURL();
    }
    
}

Paste_Image.png

从抓包结果中发现,第二次访问该站点的时候,会自动携带Cookie信息。


本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏刘望舒

LeakCanary看这一篇文章就够了

LeakCanary是Square公司基于MAT开源的一个内存泄漏检测工具,在发生内存泄漏的时候LeakCanary会自动显示泄漏信息。

3.3K50
来自专栏osc同步分享-java技术分享站

使用ResourceBundle读取配置文件

使用ResourceBundle读取配置文件的例子如下: package com.yawn; import java.io.IOException; impo...

48350
来自专栏编码小白

tomcat请求处理分析(六)servlet的处理过程

1.1.1.1  servlet的解析过程 servlet的解析分为两步实现,第一个是匹配到对应的Wrapper,第二个是加载对应的servlet并进行数据,这...

75670
来自专栏别先生

struts2使用拦截器完成登陆显示用户信息操作和Struts2的国际化

  其实学习框架,就是为了可以很好的很快的完成我们的需求,而学习struts2只是为了替代之前用的servlet这一层,框架使开发更加简单,所以作为一个小菜鸟,...

21470
来自专栏Java成神之路

Java微信公众平台开发_07_JSSDK图片上传

(2)对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式 (即 key1=value1&key2=value2…)拼接成...

43920
来自专栏LanceToBigData

JDBC(二)之JDBC处理CLOB和BLOB及事务与数据库元数据获取

前面大概介绍了JDBC连接数据库的过程,以及怎么操作数据库,今天给大家分享JDBC怎么处理CLOB和BLOB存储图片的事情,以及JDBC怎么去处理事务。怎么在插...

34850
来自专栏大内老A

为ASP.NET MVC创建一个基于Unity的ControllerFactory

谈到IoC和ASP.NET的集成,很多人会先后想到Ninject,不过我们个人还是倾向于Unity。这篇文章简单地介绍如果创建基于Unity的Controlle...

19970
来自专栏大内老A

通过一个模拟程序让你明白ASP.NET MVC是如何运行的

ASP.NET MVC的路由系统通过对HTTP请求的解析得到表示Controller、Action和其他相关的数据,并以此为依据激活Controller对象,调...

30160
来自专栏Java架构师历程

JDBC简介

简单地说,就是用于执行SQL语句的一类Java API,通过JDBC使得我们可以直接使用Java编程来对关系数据库进行操作。通过封装,可以使开发人员使用纯Jav...

11220
来自专栏恰童鞋骚年

ASP.Net请求处理机制初步探索之旅 - Part 5 ASP.Net MVC请求处理流程

开篇:上一篇我们了解了在WebForm模式下一个Page页面的生命周期,它经历了初始化Init、加载Load以及呈现Render三个重要阶段,其中构造了页面控件...

14830

扫码关注云+社区

领取腾讯云代金券