Android之Http通信——5.开发中遇到的一些问题
标签(空格分隔): 未分类
本节引言:
好吧,好久没在这里更新blog了,不是小猪偷懒了,其实是在忙一些其他的事情,本来这节是应该讲解下结合Retrofit来封装Http请求的,不过,上周在使用基本的HttpClient和HttpURLConnection做项目的时候遇到了两个问题,纠结了几天,小猪还是觉得有必要mark一下,分别是Http请求的Cookie问题和像服务器发送PUT请求的问题,没错是“PUT”而不是GET或者POST!
1.Cookie的问题
说到这个Cookie我们要先了解一点概念性的东西:Session和Cookie
1)先举个例子让大家体会下这个流程吧:
小猪输入账号密码后登陆下学校的教务系统,然后访问课表信息成功,然后如果你用的是Chrome,按F12进入开发模式:来到Resources界面可以看到我们的Cookies:
点击后我们可以看到里面保存的内容,由名称;值;cookie所在的域(domain);cookie所在的目录(path)Asp.net默认为/即根目录;过期时间;Cookie大小:
看下我们的请求头里面有个Cookie字段!
恩呢,现在我们把Cookie清掉(或者等几分钟),然后再访问下述链接:
这时候,页面竟然自动跳回登陆页面了!当然一些其他的网站可能会弹出一个对话框说“登陆超时”之类的东西!2)恩呢,这就是我们Http中的登陆,以及登陆后访问相关页面的流程:
一般是登陆的时候:服务器通过Set-Cookie响应头,返回一个Cookie,浏览器默认保存这个Cookie,后续访问相关页面的时候会带上这个Cookie,通过Cookie请求头来完成访问,如果没Cookie或者Cookie过期,就提示用户没登陆,登陆超时,访问需要登陆之类的信息!3)而我们使用HttpClient和HttpURLConnection其实也就是模拟这一个流程,登陆后拿到cookie拿着它去发请求:
HttpURLConnection中:
获得Cookie:conn.getHeaderField(“Set-Cookie”);
请求时带上Cookie:conn.setRequestProperty(“Cookie”,cookie);HttpClient中:
稍微复杂点,要使用到一个HttpResponse:
HttpResponse loginResponse = new DefaultHttpClient().execute(getLogin);
获得Cookie:cookie = loginResponse.getFirstHeader(“Set-Cookie”).getValue();
请求时带上Cookie:httpPost.setHeader(“Cookie”, cookie);好了上述就是HttpURLConnection和HttpClient获取与请求时带上Cookie的方法!
另外还有笔者纠结几天的问题是之前做请求时,服务端日志一直都是用户未登录,后来才知道是服务端那边的人没对请求头进行处理,好吧,然后服务端还一直说我的问题….醉了,另外在纠结的过程中也讨论了另外一种折衷的解决方法,“URL重写”,就是使用一个session id,Get请求的话在基本的请求参数后添加多一个:
…&sessionid=xxxxx这样,然后他服务端做解析;Post请求的话,在表单中添加一个字段,代码示例如下:这里我们用的是JSON字符串的形式,接到请求时服务端取出session里的内容,然后做下查询即可~
4)最后说回Session和Cookie的区别,Cookie只是Session机制的一种形式,我们也可以使用其他方式来作为客户端的一个唯一标识,比如上面的“URL重写”
2.Put请求的处理:
Put请求对于很多朋友来说可能有点陌生,毕竟我们平时接触的比较多的情况都是GET和POST,一开始小猪也不知道,不过后来才发现和POST其实是差不多的,而且我们只需在POST的基础上改点东西就可以使用了!而HttpClient也给我们提供了一个HttpPut的API,下面贴下小猪自己项目中写的请求代码吧:
HttpURLConnection发送PUT请求示例代码如下:
public static String LoginByPut(Context mContext, String mobile, String password, int from, String devid, String version_name, int remember_me) { String resp = ""; try { HttpURLConnection conn = (HttpURLConnection) new URL(LOGIN_URL).openConnection(); conn.setRequestMethod("PUT"); conn.setReadTimeout(5000); conn.setConnectTimeout(5000); conn.setDoOutput(true); conn.setDoInput(true); conn.setUseCaches(false); String data = "mobile=" + mobile + "&password=" + password + "&from=" + from + "&devid=" + "devid" + "&version_name=" + "version_name" + "&remember_me=" + remember_me; ; // 获取输出流: OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream()); writer.write(data); writer.flush(); writer.close(); // 获取相应流对象: InputStream in = conn.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(in)); StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine()) != null) response.append(line); SPUtils.put(mContext, "session", conn.getHeaderField("Set-Cookie")); // 资源释放: in.close(); // 返回字符串 Log.e("HEHE", response.toString()); return response.toString(); } catch (Exception e) { e.printStackTrace(); } ; return "";}
使用HttpPut发送Put请求:
public static int PutActCode(String actCode, String licPlate, Context mContext) { int resp = 0; String cookie = (String) SPUtils.get(mContext, "session", ""); HttpPut httpPut = new HttpPut(PUTACKCODE_URL); httpPut.setHeader("Cookie", cookie); try { List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("activation_code", actCode)); params.add(new BasicNameValuePair("license_plate", licPlate)); httpPut.setEntity(new UrlEncodedFormEntity(params, "UTF-8")); HttpResponse course_response = new DefaultHttpClient().execute(httpPut); if (course_response.getStatusLine().getStatusCode() == 200) { HttpEntity entity2 = course_response.getEntity(); JSONObject jObject = new JSONObject(EntityUtils.toString(entity2)); resp = Integer.parseInt(jObject.getString("status_code")); return resp; } } catch (Exception e) { e.printStackTrace(); } return resp;}
3.小结:
好吧,内容还是比较简单的,其实核心就是如何获取Cookie以及发送请求的时候带上我们的Cookie,当然有些公司可能不是用的Http协议的Session来标识用户,而是使用oAuth协议,后续公司如果用到再深入研究;还说了下Put请求怎么写!嗯,下节见~
转载请注明出处:coder-pig,谢谢,请勿用于商业用途,侵权必究~
- 1楼a2683901昨天 14:41
- zhbit 够熟悉的
- Re: zpj779878443昨天 16:25
- 回复a2683901n你也zhbit的?