原文地址:http://menuz.iteye.com/blog/1282097
Android程序使用http上传文件
有时,在网络编程过程中需要向服务器上传文件。Multipart/form-data是上传文件的一种方式。
Multipart/form-data其实就是浏览器用表单上传文件的方式。最常见的情境是:在写邮件时,向邮件后添加附件,附件通常使用表单添加,也就是用multipart/form-data格式上传到服务器。
- <form action=“/TestWeb/command=UpdatePicture” method=”post” enctype=”multipart/form-data”>
- <input type=”file” name=”uploadfile1”/><br>
- <input type=”file” name=”uploadfile2”/><br>
- <input type=”submit” value=”uploadfile”>
- </form>
内容如下:
Type:multipart/form-data; boundary=-----------------------------265001916915724
-----------------------------265001916915724
Content-Disposition: form-data; name="uploadfile1"; filename="web.txt"
Content-Type: text/plain
ChinaNetSNWide
å网æ©ç 255.255.255.255 ç®å•çš„说四个255是全广æ’IP地åã‚就是用æ¥ä»DHCPæœ åŠ¡å™¨é‚£é‡Œè•å–IP地åã‚
默认网关0.0.0.0 å³æœ¬æœº
-----------------------------265001916915724
Content-Disposition: form-data; name="uploadfile2"; filename="20080116064637581.jpg"
Content-Type: image/jpeg
ÿØÿà
-----------------------------265001916915724—
注意点一:
Header 下面boundary 有27个 -(横杆)
POST Data 下面传输每个文件的开头是有29个 -
注意点二:
观察POST Data可以发现从第一个-----------------------------265001916915724
到第二个-----------------------------265001916915724之间为一个txt文件的相关
信息。
上面form提交的servlet不用实现,只是解析了http协议,为下面模拟铺垫。
下面实现android客户端上传图片到服务端的servlet
android客户端代码
- public void upload() {
- Log.d(TAG, "upload begin");
- HttpURLConnection connection = null;
- DataOutputStream dos = null;
- FileInputStream fin = null;
- String boundary = "---------------------------265001916915724";
- // 真机调试的话,这里url需要改成电脑ip
- // 模拟机用10.0.0.2,127.0.0.1被tomcat占用了
- String urlServer = "http://10.0.0.2:8080/TestWeb/command=UpdatePicture";
- String lineEnd = " ";
- String pathOfPicture = "/sdcard/aaa.jpg";
- int bytesAvailable, bufferSize, bytesRead;
- int maxBufferSize = 1*1024*512;
- byte[] buffer = null;
- try {
- Log.d(TAG, "try");
- URL url = new URL(urlServer);
- connection = (HttpURLConnection) url.openConnection();
- // 允许向url流中读写数据
- connection.setDoInput(true);
- connection.setDoOutput(true);
- connection.setUseCaches(true);
- // 启动post方法
- connection.setRequestMethod("POST");
- // 设置请求头内容
- connection.setRequestProperty("connection", "Keep-Alive");
- connection.setRequestProperty("Content-Type", "text/plain");
- // 伪造请求头
- connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
- // 开始伪造POST Data里面的数据
- dos = new DataOutputStream(connection.getOutputStream());
- fin = new FileInputStream(pathOfPicture);
- Log.d(TAG, "开始上传images");
- //--------------------开始伪造上传images.jpg的信息-----------------------------------
- String fileMeta = "--" + boundary + lineEnd +
- "Content-Disposition: form-data; name="uploadedPicture"; filename="" + pathOfPicture + """ + lineEnd +
- "Content-Type: image/jpeg" + lineEnd + lineEnd;
- // 向流中写入fileMeta
- dos.write(fileMeta.getBytes());
- // 取得本地图片的字节流,向url流中写入图片字节流
- bytesAvailable = fin.available();
- bufferSize = Math.min(bytesAvailable, maxBufferSize);
- buffer = new byte[bufferSize];
- bytesRead = fin.read(buffer, 0, bufferSize);
- while(bytesRead > 0) {
- dos.write(buffer, 0, bufferSize);
- bytesAvailable = fin.available();
- bufferSize = Math.min(bytesAvailable, maxBufferSize);
- bytesRead = fin.read(buffer, 0, bufferSize);
- }
- dos.writeBytes(lineEnd+lineEnd);
- //--------------------伪造images.jpg信息结束-----------------------------------
- Log.d(TAG, "结束上传");
- // POST Data结束
- dos.writeBytes("--" + boundary + "--");
- // Server端返回的信息
- System.out.println("" + connection.getResponseCode());
- System.out.println("" + connection.getResponseMessage());
- if (dos != null) {
- dos.flush();
- dos.close();
- }
- Log.d(TAG, "upload success-----------------------------------------");
- } catch (Exception e) {
- e.printStackTrace();
- Log.d(TAG, "upload fail");
- }
- }
服务端servlet
- import java.io.File;
- import java.io.IOException;
- import java.util.List;
- import javax.servlet.ServletException;
- import javax.servlet.annotation.WebServlet;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- // 利用该组件进行接收客户端上传的文件
- // 需要自己加载commons-fileupload-1.2.2.jar和commons-io-2.1.jar
- import org.apache.commons.fileupload.FileItem;
- import org.apache.commons.fileupload.disk.DiskFileItemFactory;
- import org.apache.commons.fileupload.servlet.ServletFileUpload;
- /**
- * Servlet implementation class ReceivePictureFromAndroid
- */
- @WebServlet("/command=UpdatePicture")
- public class ReceivePictureFromAndroid extends HttpServlet {
- private static final long serialVersionUID = 1L;
- public ReceivePictureFromAndroid() {
- super();
- }
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- }
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- try {
- DiskFileItemFactory factory = new DiskFileItemFactory();
- ServletFileUpload upload = new ServletFileUpload(factory);
- List<FileItem> list = upload.parseRequest(request);
- System.out.println(list + " list " + list.size() );
- for(FileItem item : list) {
- String paramName = item.getFieldName();
- System.out.println(paramName);
- String paramValue = item.getString();
- System.out.println(paramValue);
- if(item.isFormField() == false) {
- File f = new File("f:\img.jpg");
- item.write(f);
- System.out.println("write filt success");
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }