web 中常用的两种上传文件的方法总结

这里我们来总结整理一下常用的两种文件上传方式以及要注意的东西:

1、springmvc .MultipartFile 的上传方式。

2、org.apache.commons.fileupload 使用apache的fileuoload 来实现

当我们使用springmvc 的MultipartFile 时我们要在spring的配置文件中添加如下的配置文件:

(1)、bean的引入以及编码和上传文件大小两个属性的设置

<bean id="multipartResolver"  
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">  
        <property name="defaultEncoding" value="UTF-8" />  
  
        <property name="maxUploadSize" value="2000000000" />  
    </bean>  

(2)、控制层的代码:

public void upload2(HttpServletRequest request) {  
        // 转型为MultipartHttpRequest  
        try {  
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;  
            List<MultipartFile> fileList = multipartRequest.getFiles("file");  
            for (MultipartFile mf : fileList) {  
                if(!mf.isEmpty()){  
                      
                }  
            }  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
          
    }  

这样就简单的获取了上传文件,其实我们上传的文件就是一个MultipartFile 对象,获取了对象后我们就可以获取文件名以及输入流。

(3)、控制层的第二种方式:

public String upload(HttpServletRequest request,  
            @RequestParam(value = "file") MultipartFile[] files) {  
        try {  
            for (MultipartFile mf : files) {  
                if(!mf.isEmpty()){  
                      
                }  
            }  
  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return "upload";  
    }  

(2)、(3)、不管哪种,其实都是一样的原理,都是将上传文件转化为了对象。

这里springMVC 都为我们封装好成自己的文件对象了,转换的过程就在我们所配置的CommonsMultipartResolver这个转换器里面下面再来看看它的源码


看到这个你应该明白了,如果你配置了multipartResolver 这个bean 则程序会自动调用fileUpload 来解析request ,在控制层获取的request已经是被解析过的,所以不用在手动去调用fileUpload 的相关方法来解析这个request。但注意,如果在spring的配置文件中没有配置这个bean的话,则我们自己要在controller层调用fileUpload 的相关方法来解析request 。ok这里说了第一种使用springmvc 的MultipartFile ,但是第二种和第一种其实是一样的,第一种解析的过程由spring替我们干了,我们只需要获取数据就ok而第二种方式就是在spring 的配置文件中不配置bean 这样在控制层中我们只能自己去解析请求。

所以简单的来说其实就是一种技术的两种使用方式,第一种是配置在了spring 容器中而第二种就是不配置在spring容器中而是自己去解析请求信息。


注意:刚开始学习的时候,你肯能不了解而出现了获取不到数据的这种情况,那就是在你不知不觉中解析了两次request所以你获取不到你想要的数据,那怎么处理那其实很简单,具体看下面:

1、不在spring的配置文件中配置,则需要你在控制层调用fileupload 的方法进行解析:

@RequestMapping(value="/upload.do")
	@SuppressWarnings("unchecked")
	public void upload(HttpServletRequest  request,HttpServletResponse response) throws IOException, FileUploadException{
	     System.out.println("文件存放目录、临时文件目录准备完毕 ...");  
	     System.out.println("filePath-->:"+filePath);
	     System.out.println("tempPath-->:"+tempPath);
	     response.setContentType("text/plain;charset=utf-8");  
	     PrintWriter pw = response.getWriter();
			// 磁盘文件工厂,创建缓存文件
	         DiskFileItemFactory diskFactory = new DiskFileItemFactory();  
	         // threshold 极限、临界值,即磁盘缓存大小设置
	         diskFactory.setSizeThreshold(10*4 * 1024);  
	         // repository 贮藏室,即临时文件目录 ,设置文件的缓存路径
	         diskFactory.setRepository(new File(tempPath));  
	         ServletFileUpload upload = new ServletFileUpload(diskFactory);  
	         // 设置允许上传的最大文件大小 ,如果是-1表示没有限制
	         upload.setSizeMax(10 * 1024 * 1024);  
	         //解决上传的文件名乱码
	      	 upload.setHeaderEncoding("UTF-8");
	      	 // 3、判断用户的表单提交方式是不是multipart/form-data,这也是我们在form中设置的那个属性的值 是不是……
			 boolean bb = upload.isMultipartContent(request);
			  if (!bb) {
					 return ;
				 }
	         // 解析HTTP请求消息头 ,也就是调用方法解析提交的内容并将其组装成一个个的FileItem对象
			 // 而其中上传的一个文件就是一个FileItem对象
	         List<FileItem> fileItems = upload.parseRequest(request);
			 try {
				Iterator<FileItem> iter = fileItems.iterator();  
				  while(iter.hasNext())  
		            {  	
		                FileItem item = (FileItem)iter.next();  
		                 //按照给定的编码格式获取上传文件内容
		                String fieldValue = item.getString("UTF-8");
		                //获取标签名称
		                String tagName = item.getFieldName();
		                //获取文件名称
		                String fileName= item.getName();
		                //上传文件输入流,也就是整个上传文件的流
		                InputStream  input =  item.getInputStream();
		                System.out.println("tagName--->:"+tagName   +"fileName--->"+fileName );
		                //判断这个FileItem是不是表单属性(他能判断是上传的文件还是表单属性)
		                if(item.isFormField())  
		                {  
		                    System.out.println("处理表单内容 ...");  
		                    processFormField(item, pw);  
		                }else{  
		                    System.out.println("处理上传的文件 ...");  
		                    processUploadFile(item, pw);  
		                }  
		            }
			} catch (Exception e) {
				e.printStackTrace();
			}finally{
				pw.close();
			}  
		
	}

  /**
	   * 处理表单内容  
	   * @param item
	   * @param pw
	   * @throws Exception
	   */
    private void processFormField(FileItem item, PrintWriter pw)  
        throws Exception  
    {  
        String tagName = item.getFieldName();  
        String fileName = item.getString("utf-8");          
        pw.println(tagName + " : " + fileName + "\r\n");  
    }  

  /**
     * 处理上传的文件  
     * @param item
     * @param pw
     * @throws Exception
     */
	private void processUploadFile(FileItem item, PrintWriter pw)  
        throws Exception  
    {  
        //文件名称
        String filename = item.getName();         
        System.out.println("完整的文件名:" + filename);  
        //上传文件大小(byte)
        long fileSize = item.getSize();  
        if("".equals(filename) && fileSize == 0)  
        {             
            System.out.println("文件名为空 ...");  
            return;  
        }  
          System.out.println("filePath:-->"+filePath);
          System.out.println("filename:--->"+filename);
          //创建保存文件路径
        File uploadFile = new File(filePath +File.separator + filename);  
        if(!uploadFile.getParentFile().exists()){
        	uploadFile.getParentFile().mkdirs();
        }
        uploadFile.createNewFile();
        //将上传上来的文件内容写到指定的文件
        item.write(uploadFile);  
        //向浏览器打印
        pw.println(filename + " 文件保存完毕 ...");  
        pw.println("文件大小为 :" + fileSize + "\r\n");  
    } 

2、在spring的配置文件中配置了这个bean 则不在需要我们自己调用一个fileupload 的方法再去解析一次,而是直接使用:

/**
	 * spring mvc MultipartFile 多文件上传
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	@RequestMapping(value="/upload1.do")
	public void  upload1(HttpServletRequest  request,HttpServletResponse response) throws IOException{
		 //创建一个通用的多部分解析器  
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());  
        //判断用户的表单提交方式是不是multipart/form-data,这也是我们在form中设置的那个属性的值 是不是……
        if(multipartResolver.isMultipart(request)){  
        //判断 request 是否有文件上传,即多部分请求  
		 MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; 
		 //获取所有上传文件的名称是input标签中的名称
		 Iterator<String> iter = multipartRequest.getFileNames(); 
		 while(iter.hasNext()){
			 String name = iter.next();
			 //按照文件名称获取这个上传文件,上传文件被转化为MultipartFile 对象
			 MultipartFile  file= multipartRequest.getFile(name);
			 //获取文件名,这里的fname也是input标签中的name而不是文件名
			 String fname= file.getName();
			 //这里获取到的才是真真的文件名称 比如test.txt等这样的名称。
			  String myfname= file.getOriginalFilename();
			 //获取输入流
			 InputStream  input = file.getInputStream();
	        System.out.println("fname: "+fname  +" name: "+name +" myfname:"+myfname);
		 }
		  //这的getFiles("file")就是获取多个input标签名称为file的文件。
          List<MultipartFile> fileList = multipartRequest.getFiles("file");  
         for(MultipartFile file:fileList){
        	System.out.println("----fileList size:"+fileList.size());
        	//获取input标签中的名称
         	String name= file.getName();
         	//这里获取到的才是真真的文件名称 比如test.txt等这样的名称。
         	String  myfname= file.getOriginalFilename();
         	//获取这个文件的输入流
         	 InputStream  input = file.getInputStream();
         	System.out.println("name"+name +"myfname:"+myfname);
         }
        }
        PrintWriter p= response.getWriter();
        p.write("ok!!!");
	}

ok到这里两种使用方法也说完了,也明白了SpringMVC中servletFileUpload.parseRequest(request)解析为空获取不到数据的问题,获取不到是因为我们解析了两次,所以我们要知道,如果你在spring的配置文件中配置了,值按照2 这种方式直接使用,而如果没有配置则需要我们按照1 中的方式先去解析request 在使用!


  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值