Android(java)学习笔记157:开源框架的文件上传(只能使用Post)
1.文件上传给服务器,服务器端必然要写代码进行支持,如下:
我们新建一个FileUpload.jsp的动态网页,同时我们上传文件只能使用post方式(不可能将上传数据拼凑在url路径下),上传数据Apache给我们提供了完善的框架,我们只要引入commons-fileupload-1.2.2.jar 和 commons-io-2.0.1.jar就可以使用这个Apache给我们封装好的框架,这两个jar放到如下目录下:
WebContent/WEB-INF/lib/
引入jar包之后,接下来我们新建一个Servlet程序,命名为"UploadServlet.java",整个工程如下图:
2.PC端上传数据到服务器:
编写服务器端代码UploadServlet.java代码:
1 package com.himi.web; 2 3 import java.io.File; 4 import java.io.IOException; 5 import java.util.List; 6 7 import javax.servlet.ServletException; 8 import javax.servlet.annotation.WebServlet; 9 import javax.servlet.http.HttpServlet; 10 import javax.servlet.http.HttpServletRequest; 11 import javax.servlet.http.HttpServletResponse; 12 13 import org.apache.commons.fileupload.FileItem; 14 import org.apache.commons.fileupload.FileItemFactory; 15 import org.apache.commons.fileupload.disk.DiskFileItemFactory; 16 import org.apache.commons.fileupload.servlet.ServletFileUpload; 17 18 /** 19 * Servlet implementation class UploadServlet 20 */ 21 @WebServlet("/UploadServlet") 22 public class UploadServlet extends HttpServlet { 23 private static final long serialVersionUID = 1L; 24 25 /** 26 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 27 */ 28 protected void doPost(HttpServletRequest request, 29 HttpServletResponse response) throws ServletException, IOException { 30 // 判断上传数据是否包含文件,true--包含文件,false--不包含文件 31 boolean isMultipart = ServletFileUpload.isMultipartContent(request); 32 //如果上传数据包含文件 33 if (isMultipart) { 34 //获取servlet上下文真实的路径 35 String realpath = request.getSession().getServletContext() 36 .getRealPath("/files"); 37 //打印servlet上下文真实的路径给用户观察 38 System.out.println(realpath); 39 File dir = new File(realpath); 40 if (!dir.exists()) 41 dir.mkdirs();
//public DiskFileItemFactory()://创建一个基于硬盘的FileItem工厂。 42 FileItemFactory factory = new DiskFileItemFactory();
//创建一个文件上传处理器
43 ServletFileUpload upload = new ServletFileUpload(factory); 44 upload.setHeaderEncoding("UTF-8"); 45 try { 46 //工具类ServletFileUpload解析我们的http的post请求的参数数据,解析结果赋给一个List集合 47 //List集合中是我们form(jsp)标签中我们的每个input节点的数据 48 List<FileItem> items = upload.parseRequest(request); 49 for (FileItem item : items) { 50 //如果是一个普通的表单 51 if (item.isFormField()) { 52 String name1 = item.getFieldName();// 得到请求参数的名称 53 String value = item.getString("UTF-8");// 得到参数值 54 System.out.println(name1 + "=" + value); 55 } else {//如果里面有文件数据,就把文件写到当前servlet上下文真实路径里面,文件名称是以系统事件命名的 56 item.write(new File(dir, System.currentTimeMillis() 57 + item.getName().substring( 58 item.getName().lastIndexOf(".")))); 59 } 60 } 61 } catch (Exception e) { 62 e.printStackTrace(); 63 } 64 } 65 } 66 67 }
同时我们还要编写FileUpload.jsp代码如下:
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 2 <html> 3 <head> 4 <%@ page language="java" contentType="text/html; charset=utf-8" 5 pageEncoding="utf-8"%> 6 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 7 <title>???????</title> 8 </head> 9 <body> 10 11 <form action="UploadServlet" method="post" enctype="multipart/form-data"> 12 请选择文件上传<input type="file" name="file"> <br> 13 <input type="submit" value="提交"> <br> 14 </form> 15 16 </body> 17 </html>
运行FileUpload.jsp动态页面在Tomcat服务器上,显示效果如下:
复制路径http://localhost:8080/web/FileUpload.jsp到360浏览器上,如下:
这里我们选择文件为桌面上的一个 心得.txt ,我们提交之后,观察浏览器 和 服务器反应,如下:
浏览器的反应:
服务器的反应:
追溯到这个打印出来的路径,我们找到了我们上传的文件,如下:
打开文件,文件内容是对的。
到这里说明PC到服务器端的文件上传是没有问题的。
3.Android手机客户端上传数据到服务器:
(1)我们新建一个Android工程,如下,命名为"文件上传器",工程一览图如下:
(2)复制loopj/android-async-http的Http开源框架到项目中:
(3)布局文件activity_main.xml:
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" 6 tools:context="com.himi.upload.MainActivity" > 7 8 <EditText 9 android:id="@+id/et_path" 10 android:layout_width="wrap_content" 11 android:layout_height="wrap_content" 12 android:hint="请输入要上传文件的路径" /> 13 14 <Button 15 android:layout_width="match_parent" 16 android:layout_height="wrap_content" 17 android:onClick="upload" 18 android:text="上传" /> 19 20 <ProgressBar 21 android:id="@+id/progressBar1" 22 style="?android:attr/progressBarStyleHorizontal" 23 android:layout_width="fill_parent" 24 android:layout_height="wrap_content" /> 25 26 </LinearLayout>
布局效果如下:
(4)同时MainActivity.java:
1 package com.himi.upload; 2 3 import java.io.File; 4 import java.io.FileNotFoundException; 5 6 import org.apache.http.Header; 7 8 import android.app.Activity; 9 import android.os.Bundle; 10 import android.view.View; 11 import android.widget.EditText; 12 import android.widget.ProgressBar; 13 import android.widget.Toast; 14 15 import com.loopj.android.http.AsyncHttpClient; 16 import com.loopj.android.http.AsyncHttpResponseHandler; 17 import com.loopj.android.http.RequestParams; 18 19 public class MainActivity extends Activity { 20 private EditText et_path; 21 private ProgressBar progressBar1; 22 23 @Override 24 protected void onCreate(Bundle savedInstanceState) { 25 super.onCreate(savedInstanceState); 26 setContentView(R.layout.activity_main); 27 et_path = (EditText) findViewById(R.id.et_path); 28 progressBar1 = (ProgressBar) findViewById(R.id.progressBar1); 29 } 30 31 32 public void upload(View view) { 33 String path = et_path.getText().toString().trim(); 34 File file = new File(path); 35 if(file.exists()) { 36 String serverurl = getString(R.string.server); 37 AsyncHttpClient client = new AsyncHttpClient(); 38 RequestParams params = new RequestParams(); 39 try { 40 params.put("file", file); 41 } catch (FileNotFoundException e) { 42 // TODO 自动生成的 catch 块 43 e.printStackTrace(); 44 }//Upload a File 45 46 client.post(serverurl, params, new AsyncHttpResponseHandler() { 47 48 @Override 49 public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) { 50 Toast.makeText(MainActivity.this, "上传成功", 0).show(); 51 52 } 53 54 /** 55 * bytesWritten:当前进度 56 * totalSize:总进度 57 */ 58 @Override 59 public void onProgress(int bytesWritten, int totalSize) { 60 progressBar1.setMax(totalSize); 61 progressBar1.setProgress(bytesWritten); 62 super.onProgress(bytesWritten, totalSize); 63 } 64 65 66 @Override 67 public void onFailure(int statusCode, Header[] headers, 68 byte[] responseBody, Throwable error) { 69 Toast.makeText(MainActivity.this, "上传失败", 0).show(); 70 71 } 72 }); 73 74 }else { 75 Toast.makeText(this, "文件不存在,请检查路径", 0).show(); 76 } 77 } 78 }
在模拟器文件的文件目录,存储imgs.jpg图片文件在目录/data/imgs.ipg,如下:
然后布署程序到模拟器上,输入上面imgs.jpg文件的存在目录,点击"上传",提示"上传成功"土司:
(5)这时候服务器端出现提示信息,说明我们已经上传成功了,这个提示信息是上传文件的存放的位置:
追溯到这个目录下,我们看到了我们之前上传的imgs.jpg图片,只是这里重新以系统时间进行命名了,如下: