昨天学习了怎么连接服务器以及简单的参数传递和服务器响应请求,是采用的java的方式实现。这里封装了一个类专门用来连接服务器。采用HttpClient方式(Apache方式)封装的,可以区分doGet()请求和doPost()请求,以及带参数请求(显示提交)和不带参数请求(隐式提交)。实现过程用到了回调方式来传递服务器的响应结果。
封装的类如下:这里称为工具类,里面定义了回调接口,并持有回调接口的实列,在AsnycTask异步任务onPostExecute()方法中将服务器响应的参数传递给Activity,在Activity里实现了回调接口中的回调方法得到该参数并显示在TextView中。
package webview;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.HashMap;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import android.os.AsyncTask;
/**
* HttpClient连接网络的封装工具类
* 采用回调机制将服务器响应的参数传回给客服端
* @author scxh
*
*/
public class HttpClientConnectUtil {
public static final String DO_GET = "GET";
public static final String DO_POST = "POST";
/*定义回调接口*/
interface ConnectCallBack{
public void getConnectMsg(String msg);
}
/*注册接口*/
private ConnectCallBack mCallBack;
public void setConnectCallBack(ConnectCallBack hCallBack){
mCallBack = hCallBack;
}
/*不带参数的带参数注册接口*/
public void HttpConnectMethod(String url,final String MethodType,ConnectCallBack hCallBack){
HttpConnectMethod(url,MethodType,null,hCallBack);
}
/*带参数的 对HttpClient请求网络的一个封装*/
public void HttpConnectMethod(String url,final String MethodType,final HashMap<String,Object> parameters,ConnectCallBack hCallBack){
mCallBack = hCallBack;
new AsyncTask<String, Void, String>(){
@Override
protected String doInBackground(String... params) {
return connectAndGetMessage(params[0],MethodType,parameters);
}
protected void onPostExecute(String result) {
mCallBack.getConnectMsg(result); //回调将结果传回去
};
}.execute(url);
}
/*连接网络取数据*/
public String connectAndGetMessage(String url,String MethodType,HashMap<String,Object> parameters){
HttpClient client = new DefaultHttpClient();
HttpUriRequest request = getRequest(url,MethodType,parameters);
String msg = null;
if(request != null){
try {
HttpResponse response = client.execute(request);
if(response.getStatusLine().getStatusCode() == HttpURLConnection.HTTP_OK){ //网络请求是否成功
msg = EntityUtils.toString(response.getEntity()); //得到响应数据
}else{
msg = "网络出错";
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return msg;
}
/*将获取request的代码封装成方法*/
public HttpUriRequest getRequest(String url,String MethodType,HashMap<String,Object> parameters){
String httpUrl = url;
if(MethodType.equalsIgnoreCase(HttpClientConnectUtil.DO_GET)){ //get请求
if(parameters != null){ //参数不为空。
httpUrl = httpUrl + "?";
StringBuilder sb = new StringBuilder(httpUrl);
for(String key:parameters.keySet()){
Object values = parameters.get(key);
sb.append(key).append("=").append(values).append("&");
//http://192.168.1.112:8080/app/myweb?username=xxx&password=xxx& 就是多出一个&
}
httpUrl = sb.substring(0, sb.length()-1);
}
HttpGet getRequest = new HttpGet(httpUrl);
return getRequest;
}else if(MethodType.equalsIgnoreCase(HttpClientConnectUtil.DO_POST)){ //post请求
HttpPost postRequst = new HttpPost(httpUrl);
if(parameters != null){ //带参数的
ArrayList<BasicNameValuePair> pairs = new ArrayList<BasicNameValuePair>();
for(String key:parameters.keySet()){
Object values = parameters.get(key);
BasicNameValuePair Pair = new BasicNameValuePair(key, (String) values);
pairs.add(Pair);
}
try {
HttpEntity entity = new UrlEncodedFormEntity(pairs, "UTF-8");//设置编码字符集防止乱码
postRequst.setEntity(entity); //向请求中加载参数
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return postRequst;
}
return null;
}
}
使用的时候只需构造参数调用方法就可以了。这里附上按钮事件请求响应的代码。
<span style="white-space:pre"> </span>case R.id.httpclient_callback_btn:
String callbackurl = "http://192.168.1.112:8080/app/myweb";
HashMap<String,Object> callbackmap = new HashMap<String,Object>();
callbackmap.put("username", "admin");
callbackmap.put("password", "12321");
/*ConnectCallBack callBack = new ConnectCallBack(){
@Override
public void getConnectMsg(String msg) {
mShowMsgTxt.setText(msg + " HttpClient回调封装的工具类响应");
}
};
HttpClientConnectUtil connectUtil = new HttpClientConnectUtil();
connectUtil.setConnectCallBack(callBack);
connectUtil.HttpConnectMethod(callbackurl, "post", callbackmap);*/
/*带参数的请求*/
new HttpClientConnectUtil().HttpConnectMethod(callbackurl, HttpClientConnectUtil.DO_GET, callbackmap, new ConnectCallBack(){
@Override
public void getConnectMsg(String msg) {
mShowMsgTxt.setText(msg + " ------- HttpClient回调封装的工具类响应+++++");
}});
/*不带参数的请求
String callbackurl = "http://192.168.1.112:8080/app/and";
new HttpClientConnectUtil().HttpConnectMethod(callbackurl, HttpClientConnectUtil.DO_GET, new ConnectCallBack(){
@Override
public void getConnectMsg(String msg) {
mShowMsgTxt.setText(msg + " ------- HttpClient回调封装的工具类响应+++++");
}});*/
break;
测试都是成功的。
提炼:
若是带参数请求时,参数是通过HashMap<key,value>键值对的形式传入的,在工具类中需要将这个HashMap参数解析出来,get请求则按照规定形式追加的URL后面。post请求则是HttpEntity对象,用到了HashMap的遍历:
<span style="white-space:pre"> </span>for(String key:parameters.keySet()){
Object values = parameters.get(key);
BasicNameValuePair Pair = new BasicNameValuePair(key, (String) values);
pairs.add(Pair);
}
for-each循环遍历。