最近在用程序模拟一个web站的https登陆,而后进行一些后续操做的小玩意。先使用java程序写测试代码,测试经过移植到android。 java
java基于httpclient-4.3.1.jar开发。 android
android端使用自带的HttpClient。(sdk版本14) git
代码移植到android环境,https请求出现403(请求被拒绝),Google N久找不到答案 - -。可是java一次又一次都能成功! web
最终换jar!使用commons-httpclient-3.1.jar!业务逻辑不变,程序测试经过! apache
我!很!忧!伤!(java端能够,android端不行。) 浏览器
(jar是从http://git.oschina.net/atearsan/android-app/tree/master/libs里下的- -,我懒,直接用osc那边的)
cookie
我这个状况可能特殊,Google时也发现了其余的一些状况,顺便记录下。
app
1. 缺乏header参数. 常见的以下: tcp
post.addHeader("Referer", xx); post.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); post.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63"); post.addHeader("Host", xx);
这个就须要分析实际的请求了。能够借助一些工具分析(http/https/tcp)请求连接,常见的工具备: 工具
Fiddler
Wireshark
还有直接浏览器调式也行,可是可能不够用,请求过程不够清晰
不知道贴出来是否有实际用处,先贴出来吧。
java端:
public void login() { try { List<NameValuePair> loginParams = new ArrayList<NameValuePair>(); loginParams.add(new BasicNameValuePair("appuri", appuri)); loginParams.add(new BasicNameValuePair("useruri", useruri)); loginParams.add(new BasicNameValuePair("service", service)); loginParams.add(new BasicNameValuePair("sid", null)); loginParams.add(new BasicNameValuePair("uname", name)); loginParams.add(new BasicNameValuePair("action", action)); loginParams.add(new BasicNameValuePair("pwd", password)); HttpPost post = new HttpPost(loginURL); post.addHeader("Referer", referer); post.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); post.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63"); post.addHeader("Host", "xxxxxxxxx"); post.setEntity(new UrlEncodedFormEntity(loginParams, HTTP.UTF_8)); // 发送登陆请求 HttpResponse response = httpClient.execute(post); if (response.getStatusLine().getStatusCode() == HttpStatus.SC_MOVED_TEMPORARILY) { post.releaseConnection(); // 获取重定向地址 String location = getLocation(response); if (!"".equals(location)) { String signURL = getSignURL(location); if(!"".equals(signURL)) { signIn(signURL); } else { System.out.println("signURL为空"); } } else { System.out.println("location为空"); } } else { System.out.println("登陆出错了"); } } catch (Exception e) { e.printStackTrace(); } }
android端的实现:
public void login() { try { /* List<NameValuePair> loginParams = new ArrayList<NameValuePair>(); loginParams.add(new BasicNameValuePair("appuri", appuri)); loginParams.add(new BasicNameValuePair("useruri", useruri)); loginParams.add(new BasicNameValuePair("service", service)); loginParams.add(new BasicNameValuePair("sid", "")); loginParams.add(new BasicNameValuePair("uname", name)); loginParams.add(new BasicNameValuePair("action", action)); loginParams.add(new BasicNameValuePair("pwd", password)); HttpPost post = new HttpPost(loginURL); post.addHeader("Referer", referer); post.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); post.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63"); post.addHeader("Host", "xxx"); post.setEntity(new UrlEncodedFormEntity(loginParams, HTTP.UTF_8)); HttpResponse response = httpClient.execute(post); */ HttpClient cc = new HttpClient(); PostMethod pm = new PostMethod(loginURL); org.apache.commons.httpclient.NameValuePair[] parametersBody = { new org.apache.commons.httpclient.NameValuePair("appuri", appuri), new org.apache.commons.httpclient.NameValuePair("useruri", useruri), new org.apache.commons.httpclient.NameValuePair("service", service), new org.apache.commons.httpclient.NameValuePair("sid", ""), new org.apache.commons.httpclient.NameValuePair("uname", name), new org.apache.commons.httpclient.NameValuePair("action", action), new org.apache.commons.httpclient.NameValuePair("pwd", password) }; pm.setRequestBody(parametersBody); pm.setRequestHeader("Referer", referer); pm.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); pm.setRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63"); pm.setRequestHeader("Host", "xxx"); // int statusCode = response.getStatusLine().getStatusCode(); int statusCode = cc.executeMethod(pm); // 登陆请求 if (statusCode == HttpStatus.SC_MOVED_TEMPORARILY) { String location = getLocation(pm); // 获取重定向地址 // String location = getLocation(response); if (!TUtil.EMPTY.equals(location)) { String signURL = getSignURL(location); if(!TUtil.EMPTY.equals(signURL)) { signIn(signURL); } else { String log = "获取签到地址失败"; super.notification(TUtil.TYPE_CM_E_CODE, log); } } else { String log = "获取重定向地址失败"; super.notification(TUtil.TYPE_CM_E_CODE, log); } } else { String log = "登陆失败.状态码:"+statusCode; super.notification(TUtil.TYPE_CM_E_CODE, log); } } catch (Exception e) { Log.e(e); String log = "登陆异常:"+e.getMessage(); super.notification(TUtil.TYPE_CM_E_CODE, log); } }
// 代码真的没啥差别,android端被注释的那些就是使用自带的HttpClient,可是恰恰登陆请求一直是403.
// 换成基于commons-httpclient-3.1.jar的HttpClient,没问题了!
//
// 我还有个问题就是:android sdk 14 自带的apche HttpClient是什么年代的版本...??? java端4.3没问题- -