正文
当前手机app与服务器端通信,通常有两种方式,一种是长连接利用Socket进行连接,另一种是短连接通过Http进行连接。相较而言,短连接不损耗系统资源,只有当客户端app进行操作时才会与服务器端进行连接,而长连接客户端与服务器端是一直保持连接的,适用于服务器端主动向客户端推送信息服务,一些即时通讯。
HTTP通信协议
最近做了一个移动输液系统,用到了HTTP通信协议。以前做项目时没有用到过,自己摸索查找资料学习的。现在,我把自己对Http的理解拿出来和大家交流一下,有不对的地方,欢迎大家提出。HTTP协议通信有两种方法,一种是HttpGet,,另一种是HttpPost
HttpGet客户端
//通过HttpClient父类DefaultHttpClient获取client对象
HttpClient client=new DefaultHttpClient();
//url:服务器端和客户端当前是连在一个局域网中,180.104.151.72是服务器端的IP地址,8080是tomacat接口,MobileInfusionServer是在tomacat中运行的一个项目名称,LoginServlet是一个Servlet,loginName和loginPassword是Android端app传入服务器中的字符串。
url="http://180.104.151.72:8080/MobileInfusionServer/LoginServlet?LoginName="+loginName+"&loginPassword="+loginPassword;
//获取HttpGet方法的对象
HttpGet get=new HttpGet(url);
//响应
HttpResponse response = client.execute(get);
//statusCode是与服务器端Servlet请求返回的验证码
int statusCode = response.getStatusLine().getStatusCode();
//如果statusCode==200,说明请求成功,在Android里是HttpStatus中的SC_OK,否则返回异常
if(statusCode!=HttpStatus.SC_OK){
throw new ServiceRulesException(
"服务器端异常";
}
//接收服务器返回值,编码方式是UTF-8
String result=EntityUtils.toString(response.getEntity(), "UTF-8");
//假设服务器端返回值是success字符串
if(result.equals("success")){
}else{
throw new ServiceRulesException(
"服务器端异常";
}
HttpGet请求的服务器端LoginServlet
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//设置接收返回值的字符编码方式为UTF-8
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
//接收客户端传入的字符串loginName,LoginPassword
String loginName=request.getParameter("LoginName");
String loginPassword=request.getParameter("LoginPassword");、
//在控制台打印传入的值
System.out.println(loginName);
System.out.println(loginPassword);
/**
* text/html
*/
response.setContentType("text/html;charset-UTF-8");
/**
* 通过response.getWriter()获取out对象返回给客户端值
*/
PrintWriter out=null;
try {
out=response.getWriter();
/**
* 登陆的业务判断
*/
if(loginName.equals("zcl")&&loginPassword.equals("123")){
//登陆成功
out.print("success");
}else {
out.print("failed");
}
} finally{
if(out!=null){
out.close();
}
}
}
HttpPost : Android客户端
public class UserServiceImpl implements UserService {
private static final String TAG = "UserServiceImpl";
@Override
public void userLogin(String loginName, String loginPassword)
throws Exception {
// TODO Auto-generated method stub
Log.d(TAG, loginName);
Log.d(TAG, loginPassword);
/**
* NameValuePair----->List<NameValuePair>----->HttpEntity---->HttpPost--
* -->HttpClient
*/
HttpParams params = new BasicHttpParams();
// 通过params设置请求字符集
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
// 设置客户端和服务器连接的超时时间
HttpConnectionParams.setConnectionTimeout(params, 3000);
// 设置服务器响应的超时时间------》SocketTimeOutException
HttpConnectionParams.setSoTimeout(params, 3000);
// 配置协议和端口
SchemeRegistry schreg = new SchemeRegistry();
schreg.register(new Scheme("http", PlainSocketFactory
.getSocketFactory(), 80));
schreg.register(new Scheme("https", PlainSocketFactory
.getSocketFactory(), 433));
ClientConnectionManager conman = new ThreadSafeClientConnManager(
params, schreg);
//通过HttpClient解析url地址
HttpClient client = new DefaultHttpClient(conman, params);
String url="http://180.104.151.72:8080/MobileInfusionServer/LoginServlet";
HttpPost post = new HttpPost(url);
//将要传入服务器端的字符串放入NameValuePair
NameValuePair paramloginName = new BasicNameValuePair("LoginName",
loginName);
BasicNameValuePair paramloginPassword = new BasicNameValuePair(
"LoginPassword", loginPassword);
//传入的是两个字符串,可以放入List集合中
List<NameValuePair> parameters = new ArrayList<NameValuePair>();
parameters.add(paramloginName);
parameters.add(paramloginPassword);
post.setEntity(new UrlEncodedFormEntity(parameters, HTTP.UTF_8));
HttpResponse response = client.execute(post);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
throw new ServiceRulesException("服务器端异常");
}
String result = EntityUtils.toString(response.getEntity(), HTTP.UTF_8);
if (result.equals("success")) {
} else {
}
}
HttpPost请求的服务器端LoginServlet
和HttpGet方法一样,基于安全的角度看,建议使用Post方法
将Http连接封装成一个工具类
在一个项目中,我们通常会有很多个方法需要与服务器端进行Http连接,每个方法,我们都需要这样一步步进行连接,这样就会显得代码冗余,为了节省程序猿的工作量,我们需要将他们封装成一个工具类,每次连接时,我们只需要调用这个工具类就可以了。
package com.xzit.mobileinfusion.util;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import android.util.Log;
import com.xzit.mobileinfusion.activity.LoginActivity;
import com.xzit.mobileinfusion.service.ServiceRulesException;
public class HttpConnectUtil {
private HttpParams params;
private ClientConnectionManager conman;
private HttpClient client;
private HttpPost post;
private HttpResponse response;
public HttpConnectUtil() {
super();
/**
* NameValuePair----->List<NameValuePair>----->HttpEntity---->HttpPost--
* -->HttpClient
*/
params = new BasicHttpParams();
// 通过params设置请求字符集
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
// 设置客户端和服务器连接的超时时间
HttpConnectionParams.setConnectionTimeout(params, 3000);
// 设置服务器响应的超时时间------》SocketTimeOutException
HttpConnectionParams.setSoTimeout(params, 3000);
// 配置协议和端口
SchemeRegistry schreg = new SchemeRegistry();
schreg.register(new Scheme("http", PlainSocketFactory
.getSocketFactory(), 80));
schreg.register(new Scheme("https", PlainSocketFactory
.getSocketFactory(), 433));
conman = new ThreadSafeClientConnManager(
params, schreg);
client = new DefaultHttpClient(conman, params);
}
/**
* 连接Client,传入对象到服务上
* @param uri
* @return
*/
public String postMessage(String uri,List<NameValuePair> parameters) throws Exception{
post = new HttpPost(uri);
post.setEntity(new UrlEncodedFormEntity(parameters, HTTP.UTF_8));
response = client.execute(post);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
throw new ServiceRulesException("服务器端错误");
}
String result = EntityUtils.toString(response.getEntity(), HTTP.UTF_8);
return result;
}
/**
* 连接Client,不传入对象到服务器上,直接从服务器端获取返回值
* @param uri
* @return
*/
public String postMessage(String uri) throws Exception{
post = new HttpPost(uri);
response = client.execute(post);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
throw new ServiceRulesException("服务器端错误");
}
Log.e("aa", "66666666");
String result = EntityUtils.toString(response.getEntity(), HTTP.UTF_8);
Log.e("aa", result);
return result;
}
}
调用HttpConnectUtil工具类进行连接
package com.xzit.mobileinfusion.serviceImpl;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;
import android.util.Log;
import com.xzit.mobileinfusion.service.PatientService;
import com.xzit.mobileinfusion.util.HttpConnectUtil;
public class PatientServiceImpl implements PatientService{
private static final String TAG = "PatientServiceImpl";
/**
* 注册账号
*/
@Override
public String patientRegiter(String s_p_name, String s_sex, String s_id_card) throws Exception {
Log.d(TAG,s_p_name);
Log.d(TAG,s_id_card);
String uri = "http://192.168.1.100:8080/MobileInfusionServer/AddPatientAction";
/**
* JSON数据的封装
* **********************************************
*/
JSONObject object = new JSONObject();
object.put("p_name", s_p_name);
object.put("sex", s_sex);
object.put("id_card", s_id_card);
NameValuePair parameter = new BasicNameValuePair("Patient",
object.toString());
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(parameter);
/**
*调用HttpConnectUtil工具类进行Http连接
*/
String result = new HttpConnectUtil().postMessage(uri, params);
return result;
}