zoukankan      html  css  js  c++  java
  • android批量文件上传(android批量图片上传)

    项目中多处用到文件批量上传功能,今天正好攻克了此问题。在此写出来,以便日后借鉴。
    首先,以下架构下的批量文件上传可能会失败或者不会成功:
                1.androidclient+springMVC服务端:服务端採用org.springframework.web.multipart.MultipartHttpServletRequest作为批量上传接收类。这种搭配下的批量文件上传会失败。终于服务端仅仅会接受到一个文件。即仅仅会接受到第一个文件。可能由于MultipartHttpServletRequest对servlet原本的HttpServletRequest类进行封装,导致批量上传有问题。
                 2.androidclient+strutsMVC服务端:这种搭配下的多文件上传。本人没有亲自尝试,不做评论。

    假设有网友採用此种方式上传失败的。原因可能同1。


    接下来说明上传成功的方案:
              採用androidclient+Servlet(HttpServletRequest)进行文件上传。
              Servlet端代码例如以下:

          

    DiskFileItemFactory factory = new DiskFileItemFactory();
    		ServletFileUpload upload = new ServletFileUpload(factory);
    		try
    		{
    			List items = upload.parseRequest(request);
    			Iterator itr = items.iterator();
    			while (itr.hasNext())
    			{
    				FileItem item = (FileItem) itr.next();
    				if (item.isFormField())
    				{
    					System.out.println("表单參数名:" + item.getFieldName() + ",表单參数值:" + item.getString("UTF-8"));
    				} 
    				else
    				{
    					if (item.getName() != null && !item.getName().equals(""))
    					{
    						System.out.println("上传文件的大小:" + item.getSize());
    						System.out.println("上传文件的类型:" + item.getContentType());
    						// item.getName()返回上传文件在client的完整路径名称
    						System.out.println("上传文件的名称:" + item.getName());
    
    						File tempFile = new File(item.getName());
    						// 上传文件的保存路径
    						File file = new File(sc.getRealPath("/") + savePath, tempFile.getName());
    						item.write(file);
    						request.setAttribute("upload.message", "上传文件成功!");
    					} else
    					{
    						request.setAttribute("upload.message", "没有选择上传文件!

    "); } } } } catch (FileUploadException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); request.setAttribute("upload.message", "上传文件失败!

    "); } request.getRequestDispatcher("/uploadResult.jsp").forward(request, response);


    android端代码例如以下:

    public class SocketHttpRequester {
        /**
         *多文件上传
         * 直接通过HTTP协议提交数据到server,实现如以下表单提交功能:
         *   <FORM METHOD=POST ACTION="http://192.168.1.101:8083/upload/servlet/UploadServlet" enctype="multipart/form-data">
                <INPUT TYPE="text" NAME="name">
                <INPUT TYPE="text" NAME="id">
                <input type="file" name="imagefile"/>
                <input type="file" name="zip"/>
             </FORM>
         * @param path 上传路径(注:避免使用localhost或127.0.0.1这种路径測试。由于它会指向手机模拟器,你能够使用http://www.iteye.cn或http://192.168.1.101:8083这种路径測试)
         * @param params 请求參数 key为參数名,value为參数值
         * @param file 上传文件
         */
        public static boolean post(String path, Map<String, String> params, FormFile[] files) throws Exception{     
            final String BOUNDARY = "---------------------------7da2137580612"; //数据分隔线
            final String endline = "--" + BOUNDARY + "--
    ";//数据结束标志
            
            int fileDataLength = 0;
            for(FormFile uploadFile : files){//得到文件类型数据的总长度
                StringBuilder fileExplain = new StringBuilder();
                 fileExplain.append("--");
                 fileExplain.append(BOUNDARY);
                 fileExplain.append("
    ");
                 fileExplain.append("Content-Disposition: form-data;name=""+ uploadFile.getParameterName()+"";filename=""+ uploadFile.getFilname() + ""
    ");
                 fileExplain.append("Content-Type: "+ uploadFile.getContentType()+"
    
    ");
                 fileExplain.append("
    ");
                 fileDataLength += fileExplain.length();
                if(uploadFile.getInStream()!=null){
                    fileDataLength += uploadFile.getFile().length();
                 }else{
                     fileDataLength += uploadFile.getData().length;
                 }
            }
            StringBuilder textEntity = new StringBuilder();
            for (Map.Entry<String, String> entry : params.entrySet()) {//构造文本类型參数的实体数据
                textEntity.append("--");
                textEntity.append(BOUNDARY);
                textEntity.append("
    ");
                textEntity.append("Content-Disposition: form-data; name=""+ entry.getKey() + ""
    
    ");
                textEntity.append(entry.getValue());
                textEntity.append("
    ");
            }
            //计算传输给server的实体数据总长度
            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); OutputStream outStream = socket.getOutputStream(); //以下完毕HTTP请求头的发送 String requestmethod = "POST "+ url.getPath()+" HTTP/1.1 "; 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, */* "; outStream.write(accept.getBytes()); String language = "Accept-Language: zh-CN "; outStream.write(language.getBytes()); String contenttype = "Content-Type: multipart/form-data; boundary="+ BOUNDARY+ " "; outStream.write(contenttype.getBytes()); String contentlength = "Content-Length: "+ dataLength + " "; outStream.write(contentlength.getBytes()); String alive = "Connection: Keep-Alive "; outStream.write(alive.getBytes()); String host = "Host: "+ url.getHost() +":"+ port +" "; outStream.write(host.getBytes()); //写完HTTP请求头后依据HTTP协议再写一个回车换行 outStream.write(" ".getBytes()); //把全部文本类型的实体数据发送出来 outStream.write(textEntity.toString().getBytes()); //把全部文件类型的实体数据发送出来 for(FormFile uploadFile : files){ StringBuilder fileEntity = new StringBuilder(); fileEntity.append("--"); fileEntity.append(BOUNDARY); fileEntity.append(" "); fileEntity.append("Content-Disposition: form-data;name=""+ uploadFile.getParameterName()+"";filename=""+ uploadFile.getFilname() + "" "); fileEntity.append("Content-Type: "+ uploadFile.getContentType()+" "); outStream.write(fileEntity.toString().getBytes()); if(uploadFile.getInStream()!=null){ byte[] buffer = new byte[1024]; int len = 0; while((len = uploadFile.getInStream().read(buffer, 0, 1024))!=-1){ outStream.write(buffer, 0, len); } uploadFile.getInStream().close(); }else{ outStream.write(uploadFile.getData(), 0, uploadFile.getData().length); } outStream.write(" ".getBytes()); } //以下发送数据结束标志。表示数据已经结束 outStream.write(endline.getBytes()); BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); if(reader.readLine().indexOf("200")==-1){//读取webserver返回的数据,推断请求码是否为200。假设不是200,代表请求失败 return false; } outStream.flush(); outStream.close(); reader.close(); socket.close(); return true; } /** *单文件上传 * 提交数据到server * @param path 上传路径(注:避免使用localhost或127.0.0.1这种路径測试,由于它会指向手机模拟器,你能够使用http://www.itcast.cn或http://192.168.1.10:8080这种路径測试) * @param params 请求參数 key为參数名,value为參数值 * @param file 上传文件 */ public static boolean post(String path, Map<String, String> params, FormFile file) throws Exception{ return post(path, params, new FormFile[]{file}); } }


    FormFile类的代码例如以下

    public class FormFile {
        /* 上传文件的数据 */
        private byte[] data;
        private InputStream inStream;
        private File file;
        
        private int fileSize;
        /* 文件名 */
        private String filname;
        /* 请求參数名称*/
        private String parameterName;
        /* 内容类型 */
        private String contentType = "application/octet-stream";
        
        public FormFile(String filname, byte[] data, String parameterName, String contentType) {
            this.data = data;
            this.filname = filname;
            this.parameterName = parameterName;
            if(contentType!=null) this.contentType = contentType;
        }
        
        public FormFile(String filname, File file, String parameterName, String contentType) {
            this.filname = filname;
            this.parameterName = parameterName;
            this.file = file;
            try {
                this.inStream = new FileInputStream(file);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            if(contentType!=null) this.contentType = contentType;
        }
        
        
        
        public FormFile(InputStream inStream, int fileSize, String filname,
    			String parameterName, String contentType) {
    		super();
    		this.inStream = inStream;
    		this.fileSize = fileSize;
    		this.filname = filname;
    		this.parameterName = parameterName;
    		this.contentType = contentType;
    	}
        
        
    
    	public int getFileSize() {
    		return fileSize;
    	}
    
    	public File getFile() {
            return file;
        }
    
        public InputStream getInStream() {
            return inStream;
        }
    
        public byte[] getData() {
            return data;
        }
    
        public String getFilname() {
            return filname;
        }
    
        public void setFilname(String filname) {
            this.filname = 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;
        }
        
    }

    注:以上android端上传代码是从网上借用的。对原作者表示感谢。
         以上代码经本人測试,能正常进行多文件上传。

查看全文
  • 相关阅读:
    在WCF中使用Flag Enumerations
    WCF开发教程资源收集
    [转]WCF 4 安全性和 WIF 简介
    Asp.Net Web API 2 官网菜鸟学习系列导航[持续更新中]
    Asp.Net Web API 2第十八课——Working with Entity Relations in OData
    Asp.Net Web API 2第十七课——Creating an OData Endpoint in ASP.NET Web API 2(OData终结点)
    Asp.Net Web API 2第十六课——Parameter Binding in ASP.NET Web API(参数绑定)
    Asp.Net Web API 2第十五课——Model Validation(模型验证)
    函数 生成器 生成器表达式
    函数的进阶
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/10487246.html
  • Copyright © 2011-2022 走看看