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. android IBinder通信驱动(摘自《android深入浅出多媒体编程》)
  2. android网游开发之socket的简单设计和实现
  3. android 欢迎界面翻页效果,仿微信第一次登陆介绍翻页界面
  4. Android(安卓)Native进程间通信实例—Socket本地通信服务端进程
  5. 【Android】socket局域网通信
  6. android UDP多点广播,并自动建立Socket连接
  7. Android(安卓)Okhttp3 (二) 二次封装请求管理类
  8. Android(安卓)登陆页面 图片验证码
  9. Android基于Http协议实现文件上传功能的方法

随机推荐

  1. android 中activity,window,view的关系
  2. Android中实现Bitmap在自定义View中的放
  3. Intent的简介以及属性的详解
  4. Android(安卓)Drawable之Bitmap
  5. 【Android(安卓)Trick 5】layout_gravity
  6. Android启动界面之SplashActivity的设计
  7. Android开发者,这些技能点你点亮了吗?
  8. Android(安卓)React-Native系列之-Native
  9. Android启动模式完全解析(下)
  10. Android调试的必杀技——反汇编