当前位置: 代码迷 >> Android >> Android之Http通信——5.开发中遇到的一些有关问题
  详细解决方案

Android之Http通信——5.开发中遇到的一些有关问题

热度:18   发布时间:2016-04-28 00:19:13.0
Android之Http通信——5.开发中遇到的一些问题

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的?
  相关解决方案