在Android与服务器交互过程中,Android端使用的核心类是AsyncTask,服务器使用JSP或者HttpServlet做出响应。当然还可以利用框架,如Struts 2或Spring。本日志只做简单的交互实现,不考虑框架、安全性以及项目的复杂度。
(二)Activity或Fragment调用
AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程.
使用的优点:简单、快捷和过程可控。
使用的缺点:在使用多个异步操作和并需要进行Ui变更时,就变得复杂起来.
一、服务器
(一)利用JSP交互
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page import="org.mortbay.util.ajax.JSON"%>
<%@ page import="java.net.URLDecoder"%>
<%
// 服务器接收数据
String json = request.getParameter("__xml");
// 解码
json = URLDecoder.decode(json, "UTF-8");
HashMap parameterMap = (HashMap) JSON.parse(json);
// 服务器做出响应
parameterMap.put("server", "hello client");
// 转换为JSON串
json = JSON.toString(parameterMap);
System.out.println(json);
// 发往移动端
out.print(json);
%>
(二)利用HttpServlet交互
1 web.xml添加如下配置
<servlet>
<servlet-name>AndroidServlet</servlet-name>
<servlet-class>com.hjsj.hrms.transaction.mobileapp.AndroidServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AndroidServlet</servlet-name>
<url-pattern>/servlet/AndroidServlet</url-pattern>
</servlet-mapping>
2 AndroidServlet实现
package com.hjsj.hrms.transaction.mobileapp;
import java.io.IOException;
import java.net.URLDecoder;
import java.util.HashMap;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.mortbay.util.ajax.JSON;
/**
*
* <p>Title: AndroidServlet </p>
* <p>Description: 和移动端交互</p>
* <p>Company: 六月</p>
* <p>Create Time: 2015-1-26 上午11:27:34</p>
* @author yangj
* @version 1.0
*/
public class AndroidServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 服务器接收数据
String json = req.getParameter("__xml");
// 解码
json = URLDecoder.decode(json, "UTF-8");
// 转化为HashMap
HashMap parameterMap = (HashMap) JSON.parse(json);
// 服务器做出响应
parameterMap.put("server", "hello client");
// 转换为JSON串
json = JSON.toString(parameterMap);
System.out.println(json);
// 发往移动端
resp.setCharacterEncoding("UTF-8");
resp.getWriter().print(json);
}
}
二、Android
(一)核心类HttpAsyncTask
package com.hjsj.setting.checkVersion;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import android.os.AsyncTask;
import android.util.Log;
import com.google.gson.Gson;
/**
*
* <p>Title: AndroidServlet </p>
* <p>Description: 和服务器交换</p>
* <p>Company: 六月</p>
* <p>Create Time: 2015-1-26 上午11:27:34</p>
* @author yangj
* @version 1.0
*/
public class HttpAsyncTask extends AsyncTask<Object, Object, Object> {
@Override
protected void onCancelled() {
super.onCancelled();
// 用户调用取消时,要做的操作
}
@Override
protected void onPreExecute() {
super.onPreExecute();
// 这里是最终用户调用Excute时的接口,当任务执行之前开始调用此方法,可以在这里显示进度对话框。
}
@Override
protected void onProgressUpdate(Object... values) {
super.onProgressUpdate(values);
// 可以使用进度条增加用户体验度
}
@Override
protected Object doInBackground(Object... arg0) {
// 后台执行,比较耗时的操作都可以放在这里。
Map<Object, Object> hm = new HashMap<Object, Object>();
/* 声明网址字符串 */
// 方案一:JSP提交
String url = "http://192.192.102.111:8080/test.jsp";
// 方案二:HttpServlet提交
//String url = "http://192.192.102.111:8080/servlet/AndroidServlet";
/* 建立HTTP Post联机 */
HttpPost httpRequest = new HttpPost(url);
// Post运作传送变量必须用NameValuePair[]数组储存
List<NameValuePair> paramsList = this.getNameValuePairList();
try {
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramsList, "UTF-8");
/* 放入数据 */
httpRequest.setEntity(entity);
/* 取得HTTP response */
HttpResponse httpResponse = new DefaultHttpClient().execute(httpRequest);
/* 若状态码为200 ok */
if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
/* 取出响应字符串 */
String result = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
// json串如何转换成java对象,规则如下
Gson gson = new Gson();
hm = gson.fromJson(result, HashMap.class);
} else {
// 连接出错
Log.e("连接出错", "错误代码:" + httpResponse.getStatusLine().getStatusCode());
}
} catch (Exception e) {
e.printStackTrace();
}
return hm;
}
@Override
protected void onPostExecute(Object result) {
super.onPostExecute(result);
// 相当于Handler 处理UI的方式,在这里面可以使用在doInBackground 得到的结果处理操作UI。
Map map = (Map) result;
Log.v("接受服务器的数据", map.toString());
// 此处可通过代理模式,讲接受到的数据传输到发起请求的Activity或Fragment
}
/**
*
* @Title: getNameValuePairList
* @Description: 组装传输的数据
* @return List<NameValuePair>
*/
private List<NameValuePair> getNameValuePairList() {
List<NameValuePair> list = new ArrayList<NameValuePair>();
Map<String, Object> map = new HashMap<String, Object>();
map.put("client", "hello server");
// 转换为JSON串
Gson gson = new Gson();
String param = gson.toJson(map);
try {
// 解决传输过程中的中文乱码问题
param = URLEncoder.encode(param, "UTF-8");
// 此处param可数据加密,然后在服务器做解密操作
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
Log.v("param", param);
list.add(new BasicNameValuePair("__xml", param));
return list;
}
}
(二)Activity或Fragment调用
HttpAsyncTask task = new HttpAsyncTask();
// 发起请求
task.execute();