android学习笔记之客户端与服务端保持session登录状态
2015-08-21 18:06
489 查看
刚进公司不久,也没有具体项目任务,只有一个混合开发模式,使用AppCan开发的项目。
虽然混合开发很便捷、很高效,使用html和js就可以完成。
但我依然对android原生开发有着极高的热情,尤其是在体验了Android 5.0版本之后,更是对原生体验着迷。
所以,我利用空闲时间,使用Android原生开发,实现以下简单任务:
用户登录,查看用户信息,查看用户和领导的谈话列表。
难点:因为缺乏http通信基础,并不知道session和cookie的作用,所以在开发中绕了很多弯路,因为虽然我登录成功了,但是在查询谈话列表时,就会请求失败。
原因:经过一番学习,大概了解了session和cookie的作用,只有让服务器识别出当前登录用户的状态,才能给予其权限进行其他请求操作。
用到的知识点很多,总结一下重要的:
其中最重要的就是通过 conn.getHeaderField("set-cookie")
方法得到返回头部的cookie部分;
然后通过 cookie.substring(0, cookie.indexOf(";"))
方法取出"JSESSIONID=XXXXXX"
再次请求网络时,需要从SharedPreferences中取出该JSESSIONID
然后使用conn.setRequestProperty方法传入该cookie参数进行网络请求
再看客户端,要以ListView来显示这些谈话内容,而ListView不能识别JSON格式的数据,需要将JSON转化为List<Map<String,String>>对象方可。
具体思路是 :
·循环遍历JSONArray依次取出每个谈话的JSONObject
·在每个JSONObject中,遍历key,value对,存入map对象中
·将map对象依次存入List<Map>中
·使用SimpleAdapter将该List<Map>与ListView绑定
下面是将JSONArray转为List<Map<String,String>>对象详细实现代码:
下面是将List<Map<String,String>>对象绑定至ListView的详细实现代码:
其中,SimpleAdapter的参数依次是:
this:上下文context,用this即可
data:List<Map<String,String>>类型的要显示的数据
R.layout.list_talk:要用于显示的list布局资源
new String [ ] { "aa", "bb", "cc" }:要显示的map中的key值
new int [ ] { R.id.aa, R.id.bb, R.id.cc } :要显示到的具体的控件资源对应id
虽然混合开发很便捷、很高效,使用html和js就可以完成。
但我依然对android原生开发有着极高的热情,尤其是在体验了Android 5.0版本之后,更是对原生体验着迷。
所以,我利用空闲时间,使用Android原生开发,实现以下简单任务:
用户登录,查看用户信息,查看用户和领导的谈话列表。
难点:因为缺乏http通信基础,并不知道session和cookie的作用,所以在开发中绕了很多弯路,因为虽然我登录成功了,但是在查询谈话列表时,就会请求失败。
原因:经过一番学习,大概了解了session和cookie的作用,只有让服务器识别出当前登录用户的状态,才能给予其权限进行其他请求操作。
用到的知识点很多,总结一下重要的:
1、关于Volley框架
Volley框架是谷歌官方通信框架,适合小数据传输使用,之前使用都很顺手,可是其没有方法获取httpResponse中的header信息,即无法获取JSESSIONID,JSESSIONID是session的一个独一无二的标识,需要重写框架的方法才可以,故放弃之。2、使用HttpUrlConnection
使用HttpUrlConnection进行网络请求,涉及网络请求的操作不能在UI线程即主线程执行,需要创建内部类继承自AsyncTask异步任务处理类。其中最重要的就是通过 conn.getHeaderField("set-cookie")
方法得到返回头部的cookie部分;
然后通过 cookie.substring(0, cookie.indexOf(";"))
方法取出"JSESSIONID=XXXXXX"
private class LoginASyncTask extends AsyncTask<String, Void, String> { @Override protected String doInBackground(String... params) { mSharedPreferences = getSharedPreferences("cookie", MODE_PRIVATE);// 用来存储服务器响应cookie mEditor = mSharedPreferences.edit(); String urlPath = "http://192.168.0.31:8080/jxyy/login/check"; String result = null; try { URL url = new URL(urlPath); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("POST"); // 设置请求方法为post conn.setUseCaches(false); // 禁止用户缓存 conn.setDoOutput(true); // 必须设置:允许输出流 DataOutputStream dos = new DataOutputStream( conn.getOutputStream());// 实例化输出流对象,用于写入参数 StringBuffer paramsBuffer = new StringBuffer(); paramsBuffer.append("&username=" + params[0]); paramsBuffer.append("&password=" + params[1]); paramsBuffer.append("&flag=" + "android"); System.out.println("paramsBuffer=" + paramsBuffer.toString()); dos.writeUTF(paramsBuffer.toString());// 使用UTF格式输出该参数 dos.flush();// 输出缓冲 dos.close();// 输出关闭 if (conn.getResponseCode() == 200) { <strong>String cookie = conn.getHeaderField("set-cookie");// 获取服务器响应cookie String sessionId = cookie.substring(0, cookie.indexOf(";")); mEditor.putString("cookie", sessionId); mEditor.commit();// 将cookie存入mSharedPreferences中</strong> BufferedReader br = new BufferedReader( new InputStreamReader(conn.getInputStream())); StringBuffer sb = new StringBuffer(); String temp = ""; while ((temp = br.readLine()) != null) { sb.append(temp); } result = sb.toString(); } } catch (Exception e) { e.printStackTrace(); } return result; } }
再次请求网络时,需要从SharedPreferences中取出该JSESSIONID
然后使用conn.setRequestProperty方法传入该cookie参数进行网络请求
URL url = new URL(urlPath); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestProperty("cookie", sharedPreferences.getString("cookie",""));
3、处理返回的JSONArray数据
服务端把每个谈话内容封装为一个JSONObject对象,将满足条件的所有谈话装入一个JSONArray中,以字符串返回客户端。再看客户端,要以ListView来显示这些谈话内容,而ListView不能识别JSON格式的数据,需要将JSON转化为List<Map<String,String>>对象方可。
具体思路是 :
·循环遍历JSONArray依次取出每个谈话的JSONObject
·在每个JSONObject中,遍历key,value对,存入map对象中
·将map对象依次存入List<Map>中
·使用SimpleAdapter将该List<Map>与ListView绑定
下面是将JSONArray转为List<Map<String,String>>对象详细实现代码:
private List<HashMap<String, String>> jsonArrayToMapList(String result) { List<HashMap<String, String>> data = new ArrayList<HashMap<String, String>>();// 实例化要绑定的List对象 HashMap<String, String> talk = new HashMap<String, String>();// 用于存储单个谈话会议的map对象 try { JSONArray ja = new JSONArray(result); for (int i = 0; i < ja.length(); i++) { // 遍历JSONArray,依次取出JSONObject JSONObject jo = ja.getJSONObject(i); Iterator<String> it = jo.keys(); // 遍历JSONObject的keys while (it.hasNext()) { String key = String.valueOf(it.next()); String value = (String) jo.get(key); talk.put(key, value);// 将JSONObject中key,value转存如map } data.add(talk);// 把所有map存入list中 } } return data; }
下面是将List<Map<String,String>>对象绑定至ListView的详细实现代码:
private void bindToListView(List<HashMap<String, String>> data) { SimpleAdapter adapter = new SimpleAdapter(this, data, R.layout.list_talk, new String[] { "talktitle", "personName", "personOrg", "targetName", "targetOrg", "talkState" }, new int[] { R.id.talkTitle, R.id.talkPerson, R.id.personOrg, R.id.talkTarget, R.id.targetOrg, R.id.talkState }); lv_talks.setAdapter(adapter); }
其中,SimpleAdapter的参数依次是:
this:上下文context,用this即可
data:List<Map<String,String>>类型的要显示的数据
R.layout.list_talk:要用于显示的list布局资源
new String [ ] { "aa", "bb", "cc" }:要显示的map中的key值
new int [ ] { R.id.aa, R.id.bb, R.id.cc } :要显示到的具体的控件资源对应id
相关文章推荐
- Android性能优化典范(三)
- 查看Android SDK 版本
- Android ContentProvider 简单学习
- android开发中与后台通讯中公共参数的解决方案
- Android性能优化典范(二)
- android详情请务必保持手机屏幕不锁屏
- Android性能优化典范(一)
- Android解析xml
- android emoji 表情的制作
- android studio 中aidl文件的使用并且实现跨进程的通信
- android内存清理
- Android:实现点击AlertDialog上按钮时不关闭对话框
- [Android开发]对电话号码的判断:
- Android的学习——ubuntu下android5.1源码的make编译
- Android之TabHost布局
- 适应多行长文本的Android TextView
- Android 最火框架XUtils之注解机制详解
- Android GPS 取经纬度
- Android 最火的快速开发框架XUtils
- Android之单选按钮,复选框使用方法汇总