java 模拟web登陆httpClient并保存cookie

Posted leavescy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 模拟web登陆httpClient并保存cookie相关的知识,希望对你有一定的参考价值。

场景:调用接口完成某项操作,但是接口是强登录的,需要cookie, 且cookie会过期;服务器会限制登录的次数,如果一个账号频繁登录,则在短时间内无法正常登录,因此无法做到每调用接口一次就登录一次,且这样的效率也会比较低;

方法: 采用httpClient获取cookie, 并在接口上加入cookie校验;

核心代码:

0. 需要加入的jar包

 

技术图片
 1 import org.apache.commons.lang.StringUtils;
 2 import org.apache.commons.httpclient.HttpClient;
 3 import org.apache.commons.httpclient.methods.GetMethod;
 4 import org.apache.http.Header;
 5 import org.apache.http.HttpResponse;
 6 import org.apache.http.HttpStatus;
 7 import org.apache.http.StatusLine;
 8 import org.apache.http.client.CookieStore;
 9 
10 import org.apache.http.client.HttpClient;
11 import org.apache.http.client.methods.HttpGet;
12 import org.apache.commons.httpclient.methods.GetMethod;
13 
14 import org.apache.http.client.methods.HttpPost;
15 
16 import org.apache.http.cookie.Cookie;
17 import org.apache.http.impl.client.BasicCookieStore;
18 
19 import org.apache.http.impl.client.HttpClients;
20 import org.apache.http.protocol.BasicHttpContext;
21 import org.apache.http.protocol.HttpContext;
View Code

  需要导入pom.xml文件的依赖

 1        <dependency>
 2             <groupId>org.apache.httpcomponents</groupId>
 3             <artifactId>httpclient</artifactId>
 4             <version>4.5.5</version>
 5         </dependency>
 6         <dependency>
 7             <groupId>commons-httpclient</groupId>
 8             <artifactId>commons-httpclient</artifactId>
 9             <version>3.1</version>
10         </dependency>

 

1. 获取cookie, 其中

getUrl(loginUrl, username, password); 是将url进行拼接,loginUrl 加上登陆需要的参数拼接为一个请求
技术图片
public String getCookies(String username, String password)
        CookieStore cookieStore = new BasicCookieStore();
        HttpContext localContext = new BasicHttpContext();
        localContext.setAttribute(COOKIE_STORE, cookieStore);
        HttpClient client = HttpClients.createDefault();
        String authUrl = getUrl(loginUrl, username, password);
        System.out.println("authUrl = " + authUrl);
        HttpPost post = new HttpPost(authUrl);
        try 
            response = client.execute(post, localContext);
            StatusLine statusLine = response.getStatusLine();
            int statusCode = statusLine.getStatusCode();
            System.out.println("first execute code :" + statusCode);
            if(statusCode == HttpStatus.SC_MOVED_PERMANENTLY || statusCode == HttpStatus.SC_MOVED_TEMPORARILY)
                Header firsRedirectHeader = response.getFirstHeader("location");
                String firstRedirectUrl = firsRedirectHeader.getValue();
                HttpGet get = new HttpGet(firstRedirectUrl);
                HttpResponse getResponse = client.execute(get, localContext);
                StatusLine statusLine2 = getResponse.getStatusLine();
                int statusCode2 = statusLine2.getStatusCode();
                System.out.println("second execute code :" + statusCode2);
                System.out.println("cookie :" + cookieStore.getCookies());
                List<Cookie> cookieList = cookieStore.getCookies();
                StringBuffer tmpCookie = new StringBuffer();
                for(int i = 0 ; i < cookieList.size(); i++) 
                    tmpCookie.append(cookieList.get(i).getName()).append("=");
                    tmpCookie.append(cookieList.get(i).getValue()).append(";");
                    tmpCookie.append("domain=").append(cookieList.get(i).getDomain()).append(";");
                    tmpCookie.append("path=").append(cookieList.get(i).getPath()).append(";");
                
                get.releaseConnection();
                return tmpCookie.toString();

            
         catch (IOException e) 
            e.printStackTrace();
        finally 
            if(post != null)
                post.releaseConnection();
            
        
        return "-1";

    
View Code

2.  获取到有效的cookie, 因为第一步获取到cookie后,cookie在一段时间内可能会失效,因此为了后面接口中带入有效的cookie, 这里还需要该函数来获取真正有效的cookie;

  public String getValidCookie(String cookie)
            if(cookie.contains("DICT_SESS"))
                return cookie;
            else
                Login login = new Login();
                String validCookie = login.getCookies(username, password);
                return validCookie;
            
    

3. 真正执行接口的代码, for循环2次,第一次是去请求接口,如果接口返回的结果是403权限被拒绝,则需要调用login.getValidCookie()方法登录一次,获取真正的cookie.,然后进行第二次接口请求;

  如果接口返回的结果是0, 则表示cookie依然有效,则直接返回true;   其中参数url是需要真正请求的接口;

 1  public Boolean executeMethod(String url) 
 2         String result = "-1";
 3         for(int i = 0; i < 2; i++) 
 4             GetMethod getMethod = new GetMethod(url);
 5             getMethod.setRequestHeader("cookie", cookie);
 6             try 
 7                 httpClient.executeMethod(getMethod);
 8                 System.out.println("method result  = " + getMethod.getResponseBodyAsString());
 9                 result = getMethod.getResponseBodyAsString();
10              catch (IOException e) 
11                 e.printStackTrace();
12             
13             JSONObject obj = JSONObject.parseObject(result);
14             if ("0".equals(obj.get("err").toString())) 
15                 return true;
16             else if ("403".equals(obj.get("err").toString())) 
17                 cookie = login.getValidCookie(cookie);
18                 continue;
19             else
20                 return false;
21             
22         
23         return false;
24 
25     

4. 在类加载的时候先登录一次,保存cookie,且是全局变量;则在第3步更新cookie的时候,就可以更新该变量;

   1 Login login = new Login();

2 private String cookie = login.getCookies(username, password);

3 HttpClient httpClient = new HttpClient(); 

 

总结: 第三步判断cookie失效重新请求的实现方法有点不太好,希望大家多多交流;

以上是关于java 模拟web登陆httpClient并保存cookie的主要内容,如果未能解决你的问题,请参考以下文章

httpclient模拟登陆成功后在浏览器中打开登陆后的页面

HttpClient 模拟登陆知乎

httpClient模拟登陆校内某系统

JAVA模拟登陆教务系统

httpclient:实现有验证码的模拟登陆

java模拟登陆时,post提交,对方网页提交时是鼠标onclick触发数据交流的,我该怎么弄?