zoukankan      html  css  js  c++  java
  • 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 加上登陆需要的参数拼接为一个请求, 其中loginUrl就是登录url
    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
    // formData 里面需要填充的内容根据浏览器f12调试模式中,获取到请求的信息


    private String getUrl(String url, String username, String password){ if(StringUtils.isEmpty(url)){ System.out.println("url is empty"); return "-1"; } formData = new HashMap<String, String>(); formData.put("username", username); formData.put("password", password); formData.put("app", "web"); formData.put("product", "xxx");//产品根据实际情况定 formData.put("tp", "urstoken"); formData.put("cf", "7"); formData.put("fr", "1"); formData.put("ru", "https://xxxxxxxn"); //链接可以根据自己在浏览器的信息中拿到,不同的登录该部分地址是不一样的 formData.put("er", "https://xxxxx"); String arguments = MaptoUrl(formData); return url + arguments; }

     

    public String MaptoUrl(Map<String, String> map){
        String arguments="?";
        Iterator iterator = map.entrySet().iterator();
        Boolean first_args = true;
        while(iterator.hasNext()){
            Map.Entry entry = (Map.Entry) iterator.next();
            Object key = entry.getKey();
            Object val = entry.getValue();
            String key_str = (String) key;
            String val_str = (String) val;
            if(first_args == false){
                arguments = arguments + "&";
            }
            first_args = false;
            arguments = arguments + key_str;
            arguments = arguments + "=";
            arguments = arguments + val_str;
    
        }
        return arguments;
    }
    

      

     

    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(); 

    public static void main(String[] args) {
            Login httpclientDemo = new Login();
            org.apache.commons.httpclient.HttpClient httpClient = new org.apache.commons.httpclient.HttpClient();
            String cookie = httpclientDemo.getCookies("username", "password");
            System.out.println("final cookie = " + cookie);
            String url = yyyyy";//需要请求的url
            GetMethod getMethod = new GetMethod(url);
            getMethod.setRequestHeader("cookie", cookie);
            try {
                httpClient.executeMethod(getMethod);
                System.out.println("method result  = " + getMethod.getResponseBodyAsString());
            } catch (IOException e) {
                e.printStackTrace();
            }
    
    
        }
    

      

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

  • 相关阅读:
    浅谈Java两种并发类型——计算密集型与IO密集型
    设置线程池的大小
    Java 四种线程池newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecuto
    gitlab的简单操作
    GitHub vs GitLab:区别?
    前端小知识汇总
    花里胡哨的CSS集锦
    码云如何上传代码
    小程序自定义底部导航
    Vue实践过程中的几个问题
  • 原文地址:https://www.cnblogs.com/leavescy/p/11348733.html
Copyright © 2011-2022 走看看