Android 开发中很多涉及网络通信,因为项目中涉及过一次,当时实现方式是 Http 请求,服务器端为 C# MVC 实现,所以这里想对这种方式进行一个总结。
Android 客户端:
首先封装一个 Http 请求帮助类
HttpHelper.java
package com.iflytek.leting.net;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.CookieStore;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.AbstractHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import android.util.Log;
public abstract class HttpHelper {
private final static String TAG = "HttpHelper";
private final static String SERVER_URL = "http://10.0.0.3/Test/";
private static CookieStore cookieStore;
/**
* @descrption 上传可变参数的Http请求方法
* @author xdwang
* @create 2012-9-27下午8:06:28
* @param controllerName C# MVC中的controller
* @param actionName C# MVC中的action
* @param params 可变参数
* @return
*/
public static String invoke(String controllerName, String actionName,
List<NameValuePair> params) {
String result = null;
try {
String url = SERVER_URL + controllerName + "/" + actionName + "/";
Log.d(TAG, "url is" + url);
HttpPost httpPost = new HttpPost(url);
if (params != null && params.size() > 0) {
HttpEntity entity = new UrlEncodedFormEntity(params, "UTF-8");
httpPost.setEntity(entity);
}
DefaultHttpClient httpClient = new DefaultHttpClient();
// 添加Cookie
if (cookieStore != null) {
httpClient.setCookieStore(cookieStore);
}
HttpResponse httpResponse = httpClient.execute(httpPost);
StringBuilder builder = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(
httpResponse.getEntity().getContent()));
for (String s = reader.readLine(); s != null; s = reader.readLine()) {
builder.append(s);
}
result = builder.toString();
Log.d(TAG, "result is ( " + result + " )");
// 保存Cookie
cookieStore = ((AbstractHttpClient) httpClient).getCookieStore();
} catch (Exception e) {
Log.e(TAG, e.toString());
}
Log.d(TAG, "over");
return result;
}
public static String invoke(String controllerName, String actionName) {
return invoke(controllerName, actionName, null);
}
/**
* @descrption 通过拼接的方式构造请求内容,实现参数传输以及文件传输
* @author xdwang
* @create 2012-9-27下午7:06:20
* @param controllerName
* .NETMVC中的controllerName
* @param actionName
* .NETMVC中的actionName
* @param params
* key:为C#方法接受的参数,value为参数值,支持多个参数
* @param files
* key:为C#方法接受的参数,不要重复,value为参数值,支持上传多个附件
* @return
* @throws IOException
*/
public static String httpPostByte(String controllerName, String actionName,
Map<String, String> params, Map<String, byte[]> files)
throws IOException {
String BOUNDARY = java.util.UUID.randomUUID().toString();
String PREFIX = "--", LINEND = "\r\n";
String MULTIPART_FROM_DATA = "multipart/form-data";
String CHARSET = "UTF-8";
String url = SERVER_URL + controllerName + "/" + actionName + "/";
URL uri = new URL(url);
HttpURLConnection conn = (HttpURLConnection) uri.openConnection();
conn.setReadTimeout(5 * 1000); // 缓存的最长时间
conn.setDoInput(true);// 允许输入
conn.setDoOutput(true);// 允许输出
conn.setUseCaches(false); // 不允许使用缓存
conn.setRequestMethod("POST");
conn.setRequestProperty("connection", "keep-alive");
conn.setRequestProperty("Charsert", "UTF-8");
conn.setRequestProperty("Content-Type", MULTIPART_FROM_DATA
+ ";boundary=" + BOUNDARY);
// 首先组拼文本类型的参数
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet()) {
sb.append(PREFIX);
sb.append(BOUNDARY);
sb.append(LINEND);
sb.append("Content-Disposition: form-data; name=\""
+ entry.getKey() + "\"" + LINEND);
sb.append("Content-Type: text/plain; charset=" + CHARSET + LINEND);
sb.append("Content-Transfer-Encoding: 8bit" + LINEND);
sb.append(LINEND);
sb.append(entry.getValue());
sb.append(LINEND);
}
DataOutputStream outStream = new DataOutputStream(
conn.getOutputStream());
outStream.write(sb.toString().getBytes());
// 发送文件数据
if (files != null) {
for (Map.Entry<String, byte[]> file : files.entrySet()) {
StringBuilder sb1 = new StringBuilder();
sb1.append(PREFIX);
sb1.append(BOUNDARY);
sb1.append(LINEND);
sb1.append("Content-Disposition: form-data; name=\""
+ file.getKey() + "\"; filename=\"" + file.getKey()
+ "\"" + LINEND);
sb1.append("Content-Type: application/octet-stream; charset="
+ CHARSET + LINEND);
sb1.append(LINEND);
outStream.write(sb1.toString().getBytes());
//这里如何是File对象,则写成这种形式
// InputStream is = new FileInputStream(file.getValue());
// byte[] buffer = new byte[1024];
// int len = 0;
// while ((len = is.read(buffer)) != -1) {
// outStream.write(buffer, 0, len);
// }
outStream.write(file.getValue());
// is.close();
outStream.write(LINEND.getBytes());
}
}
// 请求结束标志
byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes();
outStream.write(end_data);
outStream.flush();
// 得到响应码
int res = conn.getResponseCode();
InputStream in = null;
if (res == 200) {
in = conn.getInputStream();
int ch;
StringBuilder sb2 = new StringBuilder();
while ((ch = in.read()) != -1) {
sb2.append((char) ch);
}
}
return in == null ? null : in.toString();
}
}
Android 中的调用:
AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {
/**
* 服务器端的返回值处理
*/
@Override
protected void onPostExecute(String result) {
Log.d(TAG, result);
try {
JSONObject json = new JSONObject(result);
uuid = json.getString("Result");
String picName = "";
String picSrc = "";
JSONObject picMap = json.getJSONObject("Message");
if (json.getJSONObject("Message") != null) {
picSrc = picMap.getString("Value");
picName = picMap.getString("Key");
}
} catch (JSONException e) {
Log.e(TAG, e.toString());
}
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
/**
* 调用Http方法请求服务器端
*/
@Override
protected String doInBackground(Void... arg0) {
try {
// 直接传普通参数;
NameValuePair param = new BasicNameValuePair("uuid", uuid);
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(param);
return HttpHelper.invoke("GuessPic", "GetNextPicture", params);
// 直接传普通参数和附件;
Map<String, String> params = new HashMap<String, String>();
params.put("content", contentTemp);
params.put("usId", guessPicture.usId);
Map<String, byte[]> files = new HashMap<String, byte[]>();
files.put("soundBytes", totalBytes);
return HttpHelper.httpPostByte("GuessPic", "SaveAudio",
params, files);
} catch (Exception e) {
Log.e(TAG, e.toString());
return null;
}
}
};
task.execute();
服务器端(C#MVC实现):
/// <summary> /// 下一张图片 /// </summary> /// <returns></returns> public JsonResult GetNextPicture(string uuid) { ResultMessage<string, KeyValuePair<string, string>> rm = new ResultMessage<string, KeyValuePair<string, string>>(); //….TODO逻辑处理 return Json(rm, JsonRequestBehavior.AllowGet); }
/// <summary> /// 保存上传一个文件和内容 /// </summary> /// <param name="content">内容</param> /// <param name="soundBytes">音频文件对象</param> /// <returns></returns> public JsonResult SaveAudio(string content, HttpPostedFileBase soundBytes, string usId) { ResultMessage<bool, object> rm = new ResultMessage<bool, object>(); byte[] bytes = new byte[soundBytes.InputStream.Length]; soundBytes.InputStream.Read(bytes, 0, bytes.Length); //….TODO逻辑处理 return Json(rm, JsonRequestBehavior.AllowGet); }