文档章节

Android 程序使用http上传文件

yolinfeng
 yolinfeng
发布于 2015/06/06 17:52
字数 751
阅读 199
收藏 1
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 = "\r\n";
        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();
	    }
	}

}


本文转载自:http://menuz.iteye.com/blog/1282097

yolinfeng
粉丝 12
博文 196
码字总数 11946
作品 0
珠海
架构师
私信 提问
[PHP]通过 PHP for Android 利用PHP编写Android应用教程

本文摘自 IT博客 http://www.zhangdafen.com 概述 Android 上的主要开发语言是Java,让很多PHPer觉得非常遗憾。但是自从ASE(Android Scripting Environment-Android脚本环境)诞生后,允许用...

81028386
2013/03/18
1K
0
在android market发布个人免费应用的步骤

写了一段时间的android应用了,只是在自己手机上面安装。 上周申请了android developer,需要一次性25美元的程序开发注册费用。费用需要用google checkout,所以还要先申请google checkout。...

鉴客
2011/09/07
3.4K
4
Android 开发者必备的十个工具(上)

原文http://www.developer.com/ws/10-must-have-android-tools-for-developers.html ByLauren Darcey & Shane Conder Android SDK有一套强大的工具帮助开发人员设计,开发,测试和发布高质量...

abel_cao
01/17
0
0
【译】使用 Google TWA 技术将 PWA 打包成 Android App

原文地址:developers.google.com/web/updates… 原文标题:Using Trusted Web Activities 译者:谢盼 校对者:张卓 Trusted Web Activities 是集成 Web 应用的新方法,你可以通过基于 Cust...

阅文前端团队
06/03
0
0
每周总结20130821——android控件的尺寸、http文件上传

Android控件的尺寸 android开发中,可以通过编写XML格式的布局文件来实现布局,也可以用纯代码进行布局,通常都是选择XML文件布局。在XML布局文件中,与控件的尺寸有关的属性有android:minHe...

Pupa
2013/08/21
290
0

没有更多内容

加载失败,请刷新页面

加载更多

CentOS 7 查找软件安装位置的方法

1、通过文件搜索查找 root@jun-virtual-machine:# find / -name "*squid*"/var/log/squid/var/spool/squid/var/lib/yum/yumdb/s/48a7dbee62d6d5962ed739a8e4fc117cf7378bfd-squid-3.5......

webcreazy
24分钟前
5
0
eureka 加入密码认证 springboot-admin 加入密码认证

1. pom.xml 加入依赖 <!-- 加入密码认证 --><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</ar......

java框架开发者
28分钟前
4
0
数字在排序数组中出现的次数

Input:nums = 1, 2, 3, 3, 3, 3, 4, 6K = 3Output:4 二分查找的练习 public int GetNumberOfK(int[] nums, int K) { int first = binarySearch(nums, K); int last = b......

Garphy
39分钟前
5
0
大厂面试经:高频率JVM面试问题整理!

JVM(Java虚拟机)简单来说就是运行Java代码的解释器,作为螺丝钉程序员JVM其实了解下就差不多啦,不懂JVM内部细节照样能写出优质的代码!但是一到造火箭、飞机的场景(面试)不懂JVM的你,会...

架构文摘
55分钟前
9
0
thinkphp5.1学习过程五——request

<?phpnamespace app\index\controller;//use \think\facade\Request;use \think\Request;/** * Class Demo3 * @package app\index\controller * 正常情况下,控制器不依赖......

大海yht
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部