页面布局:
<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"末日"爸爸。