文档章节

Android 使用自带的HttpClient进行https请求出现403的解决过程记录

atearsan
 atearsan
发布于 2014/03/05 22:34
字数 877
阅读 7.7K
收藏 4

出现的过程

    最近在用程序模拟一个web站的https登录,然后进行一些后续操作的小玩意。先使用java程序写测试代码,测试通过移植到android。

    java基于httpclient-4.3.1.jar开发。

    android端使用自带的HttpClient。(sdk版本14)

    代码移植到android环境,https请求出现403(请求被拒绝),Google N久找不到答案 - -。但是java一次又一次都能成功!

处理方法

    最终换jar!使用commons-httpclient-3.1.jar!业务逻辑不变,程序测试通过!

    我!很!忧!伤!(java端可以,android端不行。)

    (jar是从http://git.oschina.net/atearsan/android-app/tree/master/libs里下的- -,我懒,直接用osc那边的)


同样是403,其他的一些可能情况

    我这个情况可能特殊,Google时也发现了其他的一些情况,顺便记录下。

    1. 缺少header参数. 常见的如下:

        

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



    2. 缺少cookie信息.

        这个就需要分析实际的请求了。可以借助一些工具分析(http/https/tcp)请求链接,常见的工具有:

            Fiddler

            Wireshark

            还有直接浏览器调式也行,但是可能不够用,请求过程不够清晰


java端和android端部分关键代码

    不知道贴出来是否有实际用处,先贴出来吧。

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



    // java端和android代码对比结果:

    // 代码真的没啥差异,android端被注释的那些就是使用自带的HttpClient,但是偏偏登录请求一直是403.

    // 换成基于commons-httpclient-3.1.jar的HttpClient,没问题了!

    // 

    // 我还有个问题就是:android sdk 14 自带的apche HttpClient是什么年代的版本...??? java端4.3没问题- -


© 著作权归作者所有

atearsan
粉丝 28
博文 28
码字总数 10978
作品 0
深圳
程序员
私信 提问
加载中

评论(1)

码农与厨子
码农与厨子
可能是httpclient版本问题。这个东西更新每次都有改动
Android端支持HTTP和HTTPS

作者:近乎团队 Android端的网络模块在程序开发中是至关重要的,今天我们来分享下Android端如何使用http和https 技术。 1 HTTP (Hypertext transfer protocol) 超文本传输 协议 是一个基于请...

小近
2014/10/22
1.5W
4
Android 浅谈HttpClient工具类

在Android开发中我们经常会用到网络连接功能与服务器进行数据的交互,为此Android的SDK提供了Apache的HttpClient来方便我们使用各种Http服务。你可以把HttpClient想象成一个浏览器,通过它的...

Jonson
2013/07/25
754
3
HttpClient和HttpURLConnection的区别

Android 提供两个HTTP客户端,分别是HttpURLConnection客户端和Apache的HttpClient,android的AndroidHttpClient是对HttpClient的实现。这两个HTTP客户端都支持HTTPS协议、流媒体的上传和下载...

Callen
2015/08/09
1.4K
0
Java HTTP 组件库选型看这篇就够了

原文出处:行思錄 Java HTTP 组件库选型看这篇就够了 最近项目需要使用 Java 重度调用 HTTP API 接口,于是想着封装一个团队公用的 HTTP client lib. 这个库需要支持以下特性: 连接池管理,...

行思錄
2018/09/25
0
0
android httpClient 支持HTTPS的2种处理方式

问题: 项目中Android https或http请求地址重定向为HTTPS的地址,相信很多人都遇到了这个异常(无终端认证): javax.net.ssl.SSLPeerUnverifiedException: No peer certificate 解决过程: 1....

blackylin
2013/07/11
5.2W
11

没有更多内容

加载失败,请刷新页面

加载更多

上海哪里有开住宿费发票

电13564998196 陈生详情-项.目.齐.全 可先开验。-本报讯(劳动报记者陆燕婷)聚焦餐饮行业,58同城招聘研究院昨 发布数据显示,今年上半年,全国餐饮行业招聘需求增长46.18%,平均月薪6387元。...

漂迦徴fp2090
18分钟前
9
0
上海哪里有开住宿费发票

电13564998196 陈生详情-项.目.齐.全 可先开验。-本报讯(劳动报记者陆燕婷)聚焦餐饮行业,58同城招聘研究院昨 发布数据显示,今年上半年,全国餐饮行业招聘需求增长46.18%,平均月薪6387元。...

票迦徴fp2090
19分钟前
11
0
上海哪里有开住宿费发票

电13564998196 陈生幵真嘌 可先幵验。-本报讯(劳动报记者陆燕婷)聚焦餐饮行业,58同城招聘研究院昨 发布数据显示,今年上半年,全国餐饮行业招聘需求增长46.18%,平均月薪6387元。随着餐饮行...

嘌迦徴fp2090
20分钟前
19
0
上海哪里有开住宿费发票

电13564998196 陈生详情-项.目.齐.全 可先开验。-本报讯(劳动报记者陆燕婷)聚焦餐饮行业,58同城招聘研究院昨 发布数据显示,今年上半年,全国餐饮行业招聘需求增长46.18%,平均月薪6387元。...

嘌珈徴fp2090
21分钟前
13
0
上海哪里有开住宿费发票

电13564998196 陈生幵真嘌 可先幵验。-本报讯(劳动报记者陆燕婷)聚焦餐饮行业,58同城招聘研究院昨 发布数据显示,今年上半年,全国餐饮行业招聘需求增长46.18%,平均月薪6387元。随着餐饮行...

票加徴fp2090
22分钟前
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部