zoukankan      html  css  js  c++  java
  • SpringMVC中servletFileUpload.parseRequest(request)解析为空获取不到数据问题

    原因分析

    首先我们来看下Spring mvc 中文件上传的配置

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


    再来看看Controller中使用

    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();
    		}
    		
    	}

    方式二

    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";
    	}


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


    他的转换器里面就是调用common-fileupload的方式解析,然后再使用parseFileItems()方法封装成自己的文件对象 . 

    List<FileItem> fileItems = ((ServletFileUpload) fileUpload).parseRequest(request);


    大家应该发现了上面的这句代码,已经使用过fileUpload解析过request了,你在Controller里面接收到的request都已经是解析过的,你再次使用upload进行解析获取到的肯定是空,这个就是问题的所在(大家可以在servlet里面实验,看看第二次解析后能不能获取到数据,当然是不能的)


    解决方案

    1)删除Spring MVC文件上传配置

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

    在控制器里面自己完成request的解析(当然上面spring MVC提供的两种方法是不能用的,所有上传的地方都需要自己做处理)

    public void upload3(HttpServletRequest request) {
    		DiskFileItemFactory factory = new DiskFileItemFactory();
    		ServletFileUpload upload = new ServletFileUpload(factory);
    		try {
    			List<FileItem> list = upload.parseRequest(request);
    			for(FileItem item : list){
    				if(item.isFormField()){
    					
    				}else{
    					//item.write(new File(""));
    				}
    			}
    		} catch (FileUploadException e) {
    			e.printStackTrace();
    		}
    		
    	}

    2)如果是需要使用的ProgressListener监听器我们可以重写 CommonsMultipartResolver的parseRequest方法

    package com.lwp.spring.ext;
    
    import java.util.List;
    import javax.servlet.http.HttpServletRequest;
    import org.apache.commons.fileupload.FileItem;
    import org.apache.commons.fileupload.FileUpload;
    import org.apache.commons.fileupload.FileUploadBase;
    import org.apache.commons.fileupload.FileUploadException;
    import org.apache.commons.fileupload.servlet.ServletFileUpload;
    import org.springframework.web.multipart.MaxUploadSizeExceededException;
    import org.springframework.web.multipart.MultipartException;
    import org.springframework.web.multipart.commons.CommonsMultipartResolver;
    import com.lwp.listener.FileUploadListener;
    public class CommonsMultipartResolverExt extends CommonsMultipartResolver {
    	@Override
    	protected MultipartParsingResult parseRequest(HttpServletRequest request)
    			throws MultipartException {
    		FileUploadListener listener = new FileUploadListener();
    		String encoding = determineEncoding(request);
    		FileUpload fileUpload = prepareFileUpload(encoding);
    		fileUpload.setProgressListener(listener);
    		try {
    			List<FileItem> fileItems = ((ServletFileUpload) fileUpload).parseRequest(request);
    			return parseFileItems(fileItems, encoding);
    		}
    		catch (FileUploadBase.SizeLimitExceededException ex) {
    			throw new MaxUploadSizeExceededException(fileUpload.getSizeMax(), ex);
    		}
    		catch (FileUploadException ex) {
    			throw new MultipartException("Could not parse multipart servlet request", ex);
    		}
    	}
    }

    监听器方法

    import org.apache.commons.fileupload.ProgressListener;
    
    public class FileUploadListener implements ProgressListener {
    
    	@Override
    	public void update(long arg0, long arg1, int arg2) {
    		//arg0 已经上传多少字节
    		//arg1 一共多少字节
    		//arg2 正在上传第几个文件
    		System.out.println(arg0 +"	" + arg1 +"	" + arg2);
    	}
    	
    }

    配置文件改为我们自己的(这种方式的缺陷是,所有文件上传都需要使用到Listener)

    <bean id="multipartResolver"
    		class="com.lwp.spring.ext.CommonsMultipartResolverExt">
    		<property name="defaultEncoding" value="UTF-8" />
    		<property name="maxUploadSize" value="2000000000" />
    	</bean>


    注: 综上所述,如果只是普通的文件上传spring MVC 完全可以完成,如果需要使用进度条的listener前段可以使用假的进度条或者是上面的两种方式.

  • 相关阅读:
    机器学习log
    shiro教程
    开源litemall学习
    开源mall学习
    elasticsearch 踩坑
    C#工具代码
    Java开发环境搭建——Tomcat配置
    Resource leak: 'context' is never closed
    JavaScript备忘录
    Java开发环境搭建——IntelliJ Idea开发环境
  • 原文地址:https://www.cnblogs.com/esther-qing/p/6140956.html
Copyright © 2011-2022 走看看