关于android使用httpclient上传的问题

前几天,在朋友家写一个android端上传图片到服务器端的demo,当时开发环境是adt-bundle-windows-x86_64-20131030(默认sdk-android-19),jdk:1.6,64bit;服务器端使用tomcat6.0;
页面布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.uploadtest.MainActivity" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:clickable="true"
        android:onClick="choice"
        android:text="选择并上传" />

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="22dp"
        android:src="@drawable/ic_launcher" />

</RelativeLayout>


Android上传代码实现:
package com.example.uploadtest;

import java.io.File;
import java.io.IOException;

import org.apache.http.client.ClientProtocolException;

import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends ActionBarActivity {
	private ProgressDialog pd;
	private static int rc = 101;
	private ImageView imageView1;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		imageView1 = (ImageView)findViewById(R.id.imageView1);
		
		pd = new ProgressDialog(this);
	}
	
	public void choice(View view){
		Intent intent = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*");
		startActivityForResult(intent,rc);
	}
	
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		 
		  Bitmap bm = null;
		  ContentResolver resolver = getContentResolver();
		  String path = null;
		  if (requestCode == rc) {
		   try {
		 
		    Uri originalUri = data.getData();  //获得图片的uri
		    bm = MediaStore.Images.Media.getBitmap(resolver, originalUri);
		    //显得到bitmap图片
		    imageView1.setImageBitmap(bm);
		    String[] proj = {MediaStore.Images.Media.DATA};
		 
		    Cursor cursor = getContentResolver().query(originalUri, proj, null, null, null);
		    if(cursor.moveToFirst()) {
		     int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
		     path = cursor.getString(column_index);
		     Log.e("TAG-->Error", path+"");
		    }
		    cursor.close();
		    
		    if(null != path){
		    	System.out.println("start path");
			    UploadTask ut = new UploadTask();
			    ut.execute(path);
		    }
		   } catch (IOException e) {
		    Log.e("TAG-->Error", e.toString());
		   }
		  }
		 }

	
	private static String url = "http://192.168.46.99:8080/pms/UploadAction.do";
	class UploadTask extends AsyncTask<String, Integer, String>{
		@Override
		protected String doInBackground(String... arg0) {
			String f = arg0[0];
			File file = new File(f);
			try {
				UploadUtil.upload(url, file);
			} catch (ClientProtocolException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return "success";
		}
		
		@Override
		protected void onPostExecute(String result) {
			Toast.makeText(getApplicationContext(), "上传成功!", Toast.LENGTH_LONG).show();
			pd.setProgress(100);
			pd.dismiss();
		}
		
		
		@Override
		protected void onPreExecute() {
			pd.show();
			pd.setProgress(0);
		}
	}
	
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}
}

package com.example.uploadtest;

import java.io.File;
import java.io.IOException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.ContentBody;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreProtocolPNames;
import org.apache.http.util.EntityUtils;

import android.util.Log;

public class UploadUtil {

	public UploadUtil() {
		// TODO Auto-generated constructor stub
	}
	
	
	public static void upload(String url,File file) throws ClientProtocolException, IOException{
	  HttpClient httpclient = new DefaultHttpClient();
      //设置通信协议版本
      httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
      HttpPost httppost = new HttpPost(url);
      MultipartEntity mpEntity = new MultipartEntity(); //文件传输
      ContentBody cbFile = new FileBody(file);
      mpEntity.addPart("userfile", cbFile); // <input type="file" name="userfile" />  对应的
   
   
      httppost.setEntity(mpEntity);
      System.out.println("executing request " + httppost.getRequestLine());
       
      HttpResponse response = httpclient.execute(httppost);
      HttpEntity resEntity = response.getEntity();
   
      System.out.println(response.getStatusLine());//通信Ok
      String json="";
      if (resEntity != null) {
        json=EntityUtils.toString(resEntity,"utf-8");
        Log.i("UploadUtil.class", "上传结果:"+json);
      }
      if (resEntity != null) {
        resEntity.consumeContent();
      }
      httpclient.getConnectionManager().shutdown();
	}
	
}


服务器端文件接收处理:
package com.bdqn.pms.servlet;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

public class UploadAction extends HttpServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = 6345411806513871336L;

	@SuppressWarnings("unchecked")
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		DiskFileItemFactory df = new DiskFileItemFactory();
		ServletFileUpload sfu = new ServletFileUpload(df);
		sfu.setHeaderEncoding("utf-8");
		sfu.setFileSizeMax(100*1024*1024);
		resp.setCharacterEncoding("utf-8");
		try {
			List<FileItem> list = sfu.parseRequest(req);
			if(!ServletFileUpload.isMultipartContent(req)){
				return;
			}
			Map<String, String> params = new HashMap<String, String>();
			
			for(FileItem item:list){
				if(item.isFormField()){
					String name = item.getFieldName();
					String value = item.getString("utf-8");
					params.put(name, value);
				}else{
					String fileName = item.getName();
					InputStream in = item.getInputStream();
					write2FileByInputStream(in, fileName);
				}
				item.delete();
			}
			for(String s:params.keySet()){
				System.out.println("s:"+s+";value:"+params.get(s));
			}
			resp.getWriter().write("上传成功!");
		} catch (FileUploadException e) {
			e.printStackTrace();
		}
	}
	
	private void write2FileByInputStream(InputStream in,String fileName) throws IOException{
		System.out.println("fileName is:"+fileName);
//		fileName = StringUtils.replace(fileName, "\\", "/").replace("//", "/");
		File f = new File("f:/test/"+fileName);
		FileOutputStream out = new FileOutputStream(f);
		byte[] b = new byte[1024];
		int length = 0;
		while((length = in.read(b))>0){
			out.write(b, 0, length);
		}
		out.close();
		in.close();
	}
}


android端使用的jar包是httpmime-4.1.1.jar(见附件);
服务器端的jar包是:(commons-fileupload-1.2.2.jar/commons-io-2.4.jar;见附件)
然而,最终发布的运行结果死活无法按预期执行成功,各种调试、找bug;折腾半天还是么有效果。换手机测试也是不行,始终是运行到    HttpResponse response = httpclient.execute(httppost);该行代码直接退出,无异常信息,但是如果不加入文件则后台可以接收到数据。
无可奈何,第二天去公司后换了个sdk版本(android-20),再次执行居然成功了,换了个旧版本的手机(4.3)也是可以的。然后去网上一看,不少人也碰到这种问题。好家伙,就是一个版本兼容性的问题,httpclicent-4.1.1.jar在开发环境下不兼容androidsdk-19及以下版本。解决这个问题就是升级下sdk到20以上或者换个最新的adt吧,当然androidstudio也可以。兼容性问题真是java世界的类似dota"末日"爸爸。

猜你喜欢

转载自eagalwood.iteye.com/blog/2323296
今日推荐