在AChat项目的开发过程中,把对话内容、上传图片、视频是用的最多的地方。 刚开始,我一律用MultipartEntity的方法处理,毕竟这个兼容文本数据和文件数据的递交,后来经调试发现,MultipartEntity里面的StringBody内容,尽管是String,但数据送到后台,fileupload组件还是会给它建立一个临时文档,对于效率而言,这是不可取的。
于是我把纯文本递交和混杂文件一起发送的区分两个方法处理:
先来一段发送纯文本的:
/***
* 以post的方式发送数据
* @param url
* @param params
* @param timeout
* @param cookiestore
* @return
*/
private static HttpResponsex httpPost(String url,ArrayList<BasicNameValuePair> params, int timeout,
CookieStore cookiestore,String charEncoding) {
HttpResponsex result = new HttpResponsex();
HttpEntity httpEntity = null;
try {
HttpPost httpPost = new HttpPost(url);
try {
httpPost.addHeader("Accept-Encoding", "gzip, deflate");
httpPost.addHeader("Content-type", "application/x-www-form-urlencoded");
HttpParams pars = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(pars, timeout);
HttpConnectionParams.setSoTimeout(pars, timeout);
HttpConnectionParams.setSocketBufferSize(pars, 8192);
DefaultHttpClient httpClient = new DefaultHttpClient(pars);
if (cookiestore != null) {
httpClient.setCookieStore(cookiestore);
}
HttpClientParams.setRedirecting(pars, true);
httpPost.setEntity(new UrlEncodedFormEntity(params,charEncoding));
HttpResponse httpResponse;
httpResponse = httpClient.execute(httpPost);
// httpClient.getCookieStore();
int httpStatusCode = httpResponse.getStatusLine()
.getStatusCode();
// httpResponse.getHeaders(arg0)
/*
* 判斷HTTP狀態碼是否為200
*/
if (httpStatusCode == HttpStatus.SC_OK) {
httpEntity = httpResponse.getEntity();
} else {
// errorMessage = "HTTP: "+httpStatusCode;
}
result.httpEntity = httpEntity;
result.cookieStore = httpClient.getCookieStore();
} finally {
httpPost=null;
}
} catch (Exception e) {
// errorMessage = e.getMessage();
result.exception = e;
// Log.e("NetUtil-httpRequest", e.getMessage());
Log.e("NetUtil", "httpRequest", e);
}
return result;
}
调用方法:
<span style="white-space:pre"> </span>HashMap<String,Object> params=new HashMap<String,Object>();
//p为发送的对象,先将其序列化为json字串,然后放于params
params.put("_json", JsonUtils.jsonFromObject(p));
//params还可以加上其他参数,如果有需要的话
ArrayList<BasicNameValuePair> w_params=new ArrayList<BasicNameValuePair>();
for (Entry<String, Object>item:params.entrySet()){
if (item.getValue().getClass().isArray()){
for (Object v:(Object[])item.getValue()){
w_params.add(new BasicNameValuePair(item.getKey(), (String)v));
}
}
else{
w_params.add(new BasicNameValuePair(item.getKey(), (String) item.getValue()));
}
}
runnable.response=httpPost(strUrl, w_params, timeout, cookiestore,encoding);
上面的方法,fileupload组件不会把表单数据缓存到磁盘,效率要高些。若需要上传文件,则需要用MultipartEntity模式,看下面的代码:
/***
* 已post的方式发送数据
* @param url
* @param entity
* @param timeout
* @param cookiestore
* @return
*/
private static HttpResponsex httpPost(String url,MultipartEntityX entity, int timeout,
CookieStore cookiestore) {
HttpResponsex result = new HttpResponsex();
HttpEntity httpEntity = null;
try {
HttpPost httpPost = new HttpPost(url);
try {
httpPost.addHeader("Accept-Encoding", "gzip, deflate");
HttpParams pars = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(pars, timeout);
HttpConnectionParams.setSoTimeout(pars, timeout);
HttpConnectionParams.setSocketBufferSize(pars, 8192);
DefaultHttpClient httpClient = new DefaultHttpClient(pars);
if (cookiestore != null) {
httpClient.setCookieStore(cookiestore);
}
HttpClientParams.setRedirecting(pars, true);
httpPost.addHeader("content-type", "multipart/form-data; boundary=" + entity.boundary);
httpPost.setEntity(entity.entity);
HttpResponse httpResponse;
httpResponse = httpClient.execute(httpPost);
// httpClient.getCookieStore();
int httpStatusCode = httpResponse.getStatusLine()
.getStatusCode();
// httpResponse.getHeaders(arg0)
/*
* 判斷HTTP狀態碼是否為200
*/
if (httpStatusCode == HttpStatus.SC_OK) {
httpEntity = httpResponse.getEntity();
} else {
// errorMessage = "HTTP: "+httpStatusCode;
}
result.httpEntity = httpEntity;
result.cookieStore = httpClient.getCookieStore();
} finally {
httpPost=null;
}
} catch (Exception e) {
// errorMessage = e.getMessage();
result.exception = e;
// Log.e("NetUtil-httpRequest", e.getMessage());
Log.e("NetUtil", "httpRequest", e);
}
return result;
}
public static MultipartEntityX HashMapObjectToMultipartEntity(HashMap<String,Object> params,String encoding) throws UnsupportedEncodingException{
MultipartEntityX w_ret=new MultipartEntityX();
Charset chars = Charset.forName(encoding); // Setting up the encoding
w_ret.boundary="freestyle===" + System.currentTimeMillis() + "===";
w_ret.entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE,
w_ret.boundary,chars );
for (Entry e:params.entrySet()){
if (e.getValue() instanceof File){
FileBody item=new FileBody ((File) e.getValue(),"application/octet-stream");
w_ret.entity.addPart((String) e.getKey(), item);
}
else if (e.getValue().getClass().isArray()){
for (Object o:(Object[])e.getValue()){
StringBody item=new StringBody ((String) o);
w_ret.entity.addPart((String) e.getKey(), item);
}
}
else{
StringBody item=new StringBody ((String) e.getValue(), "text/plain",
chars);
w_ret.entity.addPart((String) e.getKey(), item);
}
}
return w_ret;
}
MultipartEntityX entity=NetUtil.HashMapObjectToMultipartEntity(params,ENCODING); //从HashMap对象获得MultipartEntityX
//添加额外的文件
entity.entity.addPart(item.fg_media_path, new FileBody(new File(App.LOCAL_MEDIA_STORE_PATH,item.fg_media_path), "application/octet-stream"));
发送MultipartEntity数据包
httpPost(strUrl, entity, timeout, App.cookiestore);
服务端通过下面方法接收参数:
/***
* 接收以json方式传送的参数,key为_json
*
* @param cl
* @param typeReference
* @param requestParameterMap
* @param outputUploadFiles
* --输出上传文档列表
* @return
* @throws Exception
*/
public static <T> T beanFromUrlRequestByJson(Class<?> cl,
TypeReference typeReference, HttpServletRequest request,
HashMap<String, FileItem> outputUploadFiles) throws Exception {
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (!isMultipart) { //若不是<span style="font-family: Arial, Helvetica, sans-serif;">isMultipart的,直接取参数</span>
String w_json=request.getParameter("_json");
if (w_json==null){
return beanFromUrlRequest(cl, request.getParameterMap(), false);
}
else{
return JsonUtils.readValue(w_json, typeReference);
}
}
ServletFileUpload upload = getUploadObject();
List<FileItem> items;
items = upload.parseRequest(request);
if (items == null)
return null;
T ret = null;
for (FileItem item : items) {
if (item.isFormField() && item.getFieldName().equals("_json")) {
String w_json = new String(item.get(),"UTF-8");
ret = JsonUtils.readValue(w_json, typeReference);
}
if (outputUploadFiles!=null){
if (item.isFormField()) continue;
String w_fname = "";
try {
w_fname = item.getName();
w_fname = w_fname.substring(w_fname.lastIndexOf("\\") + 1);
w_fname = w_fname.substring(w_fname.lastIndexOf("/") + 1);
} catch (Exception p_e) {
}
// Skip Empty Field
if (w_fname.compareTo("") == 0)
continue;
outputUploadFiles.put(item.getFieldName(), item);
}
}
return ret;
}