ANDROID批量文件上传(附Demo文件)

前言

此篇主要介绍android的批量文件上传(从相册选择图片并上传)。

客户端采用HttpClient和Http协议共2种上传方式。

服务端采用Spring MVC接收批量文件上传。

ANDROID客户端

1、HttpClient方式上传

准备文件

httpmime-4.1.1.jar  (源码里面libs文件夹下)

代码中需要使用到此jar文件中的MultipartEntity类。这是Apache的一个jar包,不是android自带的。

 代码

//网络请求需要开启新的线程,不能在主线程中操作
	Runnable multiThread = new Runnable() {
		
		@Override
		public void run() {
			try {
				multiUploadFile1();
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		public void multiUploadFile1 () throws UnsupportedEncodingException {
			//HttpClient对象
			HttpClient httpClient = new DefaultHttpClient();
			//采用POST的请求方式
			//这是上传服务地址http://10.0.2.2:8080/WebAppProject/main.do?method=upload2
			HttpPost httpPost = new HttpPost("http://10.0.2.2:8080/WebAppProject/main.do?method=upload2");
			//MultipartEntity对象,需要httpmime-4.1.1.jar文件。
			MultipartEntity multipartEntity = new MultipartEntity();
			//StringBody对象,参数
			StringBody param = new StringBody("参数内容");
			multipartEntity.addPart("param1",param);
			//filesPath为List<String>对象,里面存放的是需要上传的文件的地址
			for (String path:filesPath) {
				//FileBody对象,需要上传的文件
				ContentBody file = new FileBody( new File(path));
				multipartEntity.addPart("file",file);
			}
			//将MultipartEntity对象赋值给HttpPost
			httpPost.setEntity(multipartEntity);
			HttpResponse response = null;
			try {
				//执行请求,并返回结果HttpResponse
				response = httpClient.execute(httpPost);
			} catch (ClientProtocolException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			//上传成功后返回
			if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
				System.out.println("-->success");
			} else {
				System.out.println("-->failure");
			}
		}
};

运行很简单:

new Thread(multiThread).start();

2、HTTP协议上传

此种方式在网上也很多,下面的HTTP协议部分的代码是从网上Copy的。

public static String post(String path, Map<String, String> params, FormFile[] files,Handler handler) throws Exception{     
        try {
		final String BOUNDARY = "---------------------------7da2137580612"; //数据分隔线
        final String endline = "--" + BOUNDARY + "--\r\n";//数据结束标志
        int fileDataLength = 0;	//文件长度
        for(FormFile uploadFile : files){//得到文件类型数据的总长度
            StringBuilder fileExplain = new StringBuilder();
             fileExplain.append("--");
             fileExplain.append(BOUNDARY);
             fileExplain.append("\r\n");
             fileExplain.append("Content-Disposition: form-data;name=\""+ uploadFile.getParameterName()+"\";filename=\""+ uploadFile.getFilname() + "\"\r\n");
             fileExplain.append("Content-Type: "+ uploadFile.getContentType()+"\r\n\r\n");
             fileExplain.append("\r\n");
             fileDataLength += fileExplain.length();
            if(uploadFile.getInStream()!=null){
            	if (uploadFile.getFile() != null) {
            		fileDataLength += uploadFile.getFile().length();
            	} else {
            		fileDataLength += uploadFile.getFileSize();
            	}
             }else{
                 fileDataLength += uploadFile.getData().length;
             }
        }
        StringBuilder textEntity = new StringBuilder();
        for (Map.Entry<String, String> entry : params.entrySet()) {//构造文本类型参数的实体数据
            textEntity.append("--");
            textEntity.append(BOUNDARY);
            textEntity.append("\r\n");
            textEntity.append("Content-Disposition: form-data; name=\""+ entry.getKey() + "\"\r\n\r\n");
            textEntity.append(entry.getValue());
            textEntity.append("\r\n");
        }
        //计算传输给服务器的实体数据总长度
        int dataLength = textEntity.toString() .getBytes().length + fileDataLength +  endline.getBytes().length;
        
        URL url = new URL(path);
        int port = url.getPort()==-1 ? 80 : url.getPort();
        Socket socket = new Socket(InetAddress.getByName(url.getHost()), port);   
        Log.i("hbgz", "socket connected is " + socket.isConnected());
        OutputStream outStream = socket.getOutputStream();
        //下面完成HTTP请求头的发送
        String requestmethod = "POST "+ url.getPath()+" HTTP/1.1\r\n";
        outStream.write(requestmethod.getBytes());
        String accept = "Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*\r\n";
        outStream.write(accept.getBytes());
        String language = "Accept-Language: zh-CN\r\n";
        outStream.write(language.getBytes());
        String contenttype = "Content-Type: multipart/form-data; boundary="+ BOUNDARY+ "\r\n";
        outStream.write(contenttype.getBytes());
        String contentlength = "Content-Length: "+ dataLength + "\r\n";
        outStream.write(contentlength.getBytes());
        String alive = "Connection: Keep-Alive\r\n";
        outStream.write(alive.getBytes());
        String host = "Host: "+ url.getHost() +":"+ port +"\r\n";
        outStream.write(host.getBytes());
        //写完HTTP请求头后根据HTTP协议再写一个回车换行
        outStream.write("\r\n".getBytes());
        //把所有文本类型的实体数据发送出来
        outStream.write(textEntity.toString().getBytes());
        int lenTotal = 0;
        //把所有文件类型的实体数据发送出来
        for(FormFile uploadFile : files){
            StringBuilder fileEntity = new StringBuilder();
             fileEntity.append("--");
             fileEntity.append(BOUNDARY);
             fileEntity.append("\r\n");
             fileEntity.append("Content-Disposition: form-data;name=\""+ uploadFile.getParameterName()+"\";filename=\""+ uploadFile.getFilname() + "\"\r\n");
             fileEntity.append("Content-Type: "+ uploadFile.getContentType()+"\r\n\r\n");
             outStream.write(fileEntity.toString().getBytes());
             InputStream is = uploadFile.getInStream();
             if(is!=null) {
                 byte[] buffer = new byte[1024];
                 int len = 0;
	                 while((len = is.read(buffer, 0, 1024))!=-1){
	                     outStream.write(buffer, 0, len);
	                     lenTotal += len;	//每次上传的长度
	                     Message message = new Message();
	                     message.arg1 = 11;
	                     message.obj = lenTotal;
	                     handler.sendMessage(message);
	                 }
	                 is.close();   
             }else{
                 outStream.write(uploadFile.getData(), 0, uploadFile.getData().length);
             }
             outStream.write("\r\n".getBytes());
        }
        //下面发送数据结束标志,表示数据已经结束
        outStream.write(endline.getBytes());
        
        BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String str = "";
        boolean requestCodeSuccess = false;
        boolean uploadSuccess = false;
        int indexResult = 1;
        while((str = reader.readLine()) != null) {
        	Log.d("yjw", "upload--->str=" + str);
        	if (indexResult == 1) {
        		if (str.indexOf("200") > 0) {
            		requestCodeSuccess = true;
            	}
        	}
        	if (indexResult == 6) {
        		if ("true".equals(str.trim())) {
            		uploadSuccess = true;
            	}
        	}
        	
        	if (requestCodeSuccess && uploadSuccess) {
        		
        		outStream.flush();
    	        if(null != socket && socket.isConnected())
    	        {
	    	        socket.shutdownInput();
	    	        socket.shutdownOutput();
    	        }
    	        outStream.close();
    	        reader.close();
    	        socket.close();
        		return str.trim();
        	} else if (indexResult == 6) {
        		outStream.flush();
    	        if(null != socket && socket.isConnected())
    	        {
	    	        socket.shutdownInput();
	    	        socket.shutdownOutput();
    	        }
    	        outStream.close();
    	        reader.close();
    	        socket.close();
        		return str.trim();
        	}
        	++indexResult;
        }
        outStream.flush();
       
        if(null != socket && socket.isConnected())
        {
	        socket.shutdownInput();
	        socket.shutdownOutput();
        }
        outStream.close();
        reader.close();
        socket.close();
        return null;
        } catch(Exception e) {
        	e.printStackTrace();
        	 return null;
        }
    }

FormFile类:

/**
 * 上传文件
 */
public class FormFile {
    /* 上传文件的数据 */
    private byte[] data;
    private InputStream inStream;
    private File file;
    //上传文件大小
    private int fileSize;
    /* 上传文件名称,可以作为服务器上显示的文件名称*/
    private String filename;
    /* 请求参数名称 <input type="file" name="file" /> 对应的是input中的name*/
    private String parameterName;
    /* 内容类型 */
    private String contentType = "application/octet-stream";
    
    public FormFile(String filname, File file, String parameterName, String contentType) {
        this.filename = filname;
        this.parameterName = parameterName;
        this.file = file;
        if (this.file == null) {
        	throw new NullPointerException("file 不能为空");
        }
        if(contentType!=null) this.contentType = contentType;
    }
    
	public int getFileSize() {
		return fileSize;
	}

	public File getFile() {
        return file;
    }

    public InputStream getInStream() {
    	if (inStream != null) {
    		try {
				inStream.close();
				inStream = null;
			} catch (IOException e) {
				e.printStackTrace();
			}
    	}
    	try {
            this.inStream = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        return inStream;
    }

    public byte[] getData() {
        return data;
    }

    public String getFilname() {
        return filename;
    }

    public void setFilname(String filname) {
        this.filename = filname;
    }

    public String getParameterName() {
        return parameterName;
    }

    public void setParameterName(String parameterName) {
        this.parameterName = parameterName;
    }

    public String getContentType() {
        return contentType;
    }

    public void setContentType(String contentType) {
        this.contentType = contentType;
    }
    
}

调用方式:

/**
     * 上传图片到服务器,此段代码需要在新线程中运行
     * 
     * @param formFiles FormFile数组。
     */
    public String uploadFile(FormFile[] formFiles) {
        try {
            //请求普通信息
            Map<String, String> params = new HashMap<String, String>();
            params.put("method", "upload");
            //如果是本机使用10.0.2.2
            String result = SocketHttpRequester.post("http://10.0.2.2:8080/WebAppProject/main.do", params, formFiles,mHandler);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

JAVA服务端

采用的Spring MVC的方式。在springmvc-servlet.xml文件中需要加入下面代码:

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<!-- 解析request的编码 ,Default is ISO-8859-1 -->
		<property name="defaultEncoding">
		    <value>UTF-8</value>
		</property>
	</bean>

Spring MVC其他的基本配置就不在这里多说了。不清楚的可以看源码,并在网上找资料查看。

用于接收上传文件的Controller代码如下:

@Controller
@RequestMapping("/main.do")
public class MainController {

	@RequestMapping(params="method=upload")
	public String uploadFile(MultipartHttpServletRequest request) {
		System.out.println("--->uploadFile");
		//1、此种方式不需要知道input的name值----下面方法2的“file”值,方法1不需要知道是多少
		MultiValueMap<String,MultipartFile> multiMap = request.getMultiFileMap();
		Set<String> keys = multiMap.keySet();
		for (String key:keys) {
			List<MultipartFile> mutiFile = multiMap.get(key);
				writeFileToDisk(mutiFile);
		}
		
		//2、request.getFiles("file")
		//其中的"file"是<input type="file" name="file" />中的name值
		//或者是android代码中HTTP协议上传的FormFile.parameterName值
		//或者是android代码中的HttpClient中的multipartEntity.addPart("file",file);
//		List<MultipartFile> fileList = request.getFiles("file");
//		writeFileToDisk(fileList);
		
		//跳转的网页,对应success.jsp
		return "success";
	}
	
	private void writeFileToDisk(List<MultipartFile> fileList) {
		for (MultipartFile file : fileList) {
			InputStream is = null;
			FileOutputStream fos = null;
			try {
			System.out.println("--->"+file.getSize());
				is =  file.getInputStream();
				fos = new FileOutputStream("D:/a/"+System.currentTimeMillis()+".png");
				
				byte[] buffer = new byte[1024];
				int len=0;
				while ((len = is.read(buffer)) != -1) {
					fos.write(buffer, 0, len);
				} 
				fos.flush();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				try {
					if (fos != null) {
						fos.close();
					}
					if (is != null) {
						is.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
				
			}
		}
	}
}

附上JSP上传的代码(源码中的upload.jsp):

 <form action="main.do?method=upload" method="post" enctype="multipart/form-data">
    Upload1:<input type="file" name="file" /><br/>
    Upload2:<input type="file" name="file" /><br/>
    <input type="submit" title="upload" />
    </form>


以上需要注意的是android客户段代码中什么属性值和JSP中的参数对应-----这个在代码注释中有强调。

源码地址:android批量文件上传Demo

Demo中是从相册选择图片上传,因为各个版本的android系统原因,在打开相册获取图片的方法写的比较全(此处代码也有点多)。需要的也可以直接拷贝使用。



 


  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杨景文Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值