• Android的HttpClient调用,冲突的解决办法


    只适用部分情况

    题外话

    攻关百度自动发贴作推广失败,但登录已拿下。全扔有点浪费。

    在登录的基础上写了个百度的自动签到系统,功能已实现([java,android,nodejs,.net]+nodejs)

    用nodejs是我没摸清楚百度的RSA加密算法,试了很多都失败,索性就直接把百度的RSA加密过程提取出来,移到nodejs了(都是JS)。

    成功后又想了想,可以把.net实现迁移到JAVA,写个安卓百度签到的APP的应用,练练手复习安卓。

    迁到JAVA的过程非常顺利,但是到Android就进了几个坑。

    .NET 获取token代码 ,用微软给的HttpWebRequest和 Newtonsoft.Json DLL

     1  public string GetToken(CookieContainer cookies) {
     2             string token = "";
     3             DateTime dt = DateTime.Now;
     4             string tt = TimeUtils.ConvertDateTimeInt(dt).ToString() + "000";
     5             //这一步获取必定失败,更主要是为了获取百度的一些其他信息。
     6             token = NetHelper.HttpGet("https://passport.baidu.com/v2/api/?getapi&tpl=tb&apiver=v3&tt=" + tt + "&class=login&logintype=dialogLogin", ref cookies);
     7             //这一步会获取成功。
     8             token = NetHelper.HttpGet("https://passport.baidu.com/v2/api/?getapi&tpl=tb&apiver=v3&tt=" + tt + "&class=login&logintype=dialogLogin", ref cookies);
     9             JObject jo1 = (JObject)JsonConvert.DeserializeObject(token);
    10             string tokenstring = jo1["data"]["token"].ToString();
    11             return tokenstring;
    12         }

    封装的Http API

      public static string HttpGet(string Url, ref CookieContainer cookie)
            {
                string strResult =string.Empty;
                try
                {
                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
                    //request.Referer = "http://www.wangpiao.com/movie/25149/?showulcinfo=1";
                    request.Headers.Set("Pragma", "no-cache");
                    request.CookieContainer = cookie;
                    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                    Stream streamReceive = response.GetResponseStream();
                    Encoding encoding = Encoding.GetEncoding("UTF-8");
                    StreamReader streamReader = new StreamReader(streamReceive, encoding);
                    strResult = streamReader.ReadToEnd();
                    cookie.Add(response.Cookies);
                }
                catch (Exception ex)
                {
                    //MessageBox.Show(ex.ToString()+"出错");
                }
                return strResult;
            }

    迁到JAVA引用Apache httpclient4.3.5,和GSON JSON解析包。

     private static String GetTimeString(){
            Date now = new Date(); 
         return now.getTime()+"";
        }
         public  void GetToken()throws Exception {
             CloseableHttpClient httpclient = HttpClients.custom()
                        .setDefaultCookieStore(cookies)
                        .build();       
               String tt=GetTimeString();
               try {
                   
                   HttpGet httpget = new HttpGet("https://passport.baidu.com/v2/api/?getapi&tpl=tb&apiver=v3&tt=" + tt + "&class=login&logintype=dialogLogin");
                 CloseableHttpResponse response1 = httpclient.execute(httpget);
                 try {
                     response1 = httpclient.execute(httpget);
                     ByteArrayInputStream bis = new ByteArrayInputStream(EntityUtils.toByteArray(response1.getEntity()));  
                     String ss=convertStreamToString(bis).replace("/n", "");
                     JsonParser jsonparer = new JsonParser();//初始化解析json格式的对象
                     token = jsonparer.parse(ss).getAsJsonObject().get("data").getAsJsonObject().get("token").getAsString();
                 } finally {
                     response1.close();
                 }
               }finally {
                  httpclient.close();
             }
         } 
    public static String convertStreamToString(InputStream is) {   
               BufferedReader reader = new BufferedReader(new InputStreamReader(is));   
                    StringBuilder sb = new StringBuilder();   
                    String line = null;   
                    try {   
                        while ((line = reader.readLine()) != null) {   
                            sb.append(line + "/n");   
                        }   
                    } catch (IOException e) {   
                        e.printStackTrace();   
                    } finally {   
                        try {   
                            is.close();   
                        } catch (IOException e) {   
    
                            e.printStackTrace();   
                        }   
                    }   
                    return sb.toString();   
                }   

    OK,JAVA+NODEJS也已实现。

    就差一步了,JAVA到android不是很容易嘛,结果这一步坑了我两个小时

    首先 编译不过

    之后 运行出错

    根本原因都是因为android自带了个httpclient的包。和引用的httpclient4.3.5冲突。

    询问得知几种方法

    一:有就让用anroid的(这不是费话么,用android的能解决我干嘛要引,android(版本 19)的自带的包不支持cookie,开发要用的)

    二:有说拿httpclient4.3.5源码改包名重打包编译的,折腾

    三:有说扒个开源实现的(开源中国已扒),自已实现的一个精简的request包,自实现cookie,代码差距太太,几乎要重写,也折腾。

    四:这是自已无意翻来的,搜了一个回答说4.3.3不冲突,顺道看了看http://hc.apache.org/downloads.cgi,冲突不冲突,我还不知道,不过眼前一亮,发现了这个

    HttpClient for Android 4.3.5 (GA)

    这就是主角了,满心欢喜的引了,几翻处理完,OK,编译过了,执行,还是报错

    不过这包是直接给的源码,追下去,找到办法了,异常堆栈的大概印象。

    Args.NotNull:item may not be null

    RegisterBuilder.register  Arg.notNull

    HttpClientBuilder register("https",sslSocketFactory)

    sslSocketFactory 这玩意为null了。

    builder里有sslSocketFactory 的新建实例操作,追下去,发现不进。

    原因是systemProperties默认的值为false。

    搜systemProperties 发现一个方法会设置该值,调用,这下总算是OK了。

    对比下

    JAVA调用

    CloseableHttpClient httpclient = HttpClients.custom()
                        .setDefaultCookieStore(cookies)
                        .build();       

    Android修改为

     CloseableHttpClient httpclient = HttpClients.custom().useSystemProperties()
                        .setDefaultCookieStore(cookies)
                        .build();       

    这下一切OK了

    对了,Android还要记得设INTERNET权限

    android app百度贴吧签到核心功能已实现。

  • 相关阅读:
    __proto__和[[Prototype]]的区别
    JavaScript将类数组转换为数组的三种方法
    VMware报错:在该 VMware Workstation 实例中打开了最大数量的标准虚拟机。 必须在打开新的虚拟机
    bd09坐标转wgs84 JS版本 精准度高
    Layui,table,点击tool按钮获取index
    Layui扩展第三方
    Layui,table,获取当前页码数
    solidwork模型格式转为glb并且压缩
    three.js加载模型,鼠标操作模型,点击获取对象信息
    类似若依的springspringboot+vue后端框架
  • 原文地址:https://www.cnblogs.com/zihunqingxin/p/4040037.html
Copyright © 2020-2023  润新知