SpringMVC实现文件上传

方法一:

在Spring配置文件里配置下面这个拦截器

    <!-- 上传文件拦截,设置最大上传文件大小 1G -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="1073741824"/>
    </bean>

则在Controller方法里可以通过下面的方法获取上传的文件。这跟用Servlet时是一样的。

	@RequestMapping(value="uploadFile", method=RequestMethod.POST)
	public @ResponseBody String uploadFile(HttpServletRequest request) {
		System.out.println("***** uploadFile *****");
		
		FileItemFactory factory = new DiskFileItemFactory();
		ServletFileUpload upload = new ServletFileUpload(factory);
		
		try {
			List<FileItem> items = upload.parseRequest(request);
			for (FileItem item : items) {
				if (null != item.getName() && item.getName().trim() != "") {
					System.out.println("item name: " + item.getName());
//					file = new File(uploadPath + item.getName());
//					item.write(file);
				}
			}
		} catch (FileUploadException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return "complete";
	}

方法二:

如果在Spring配置文件里配置了上面的拦截器,在Controller的方法里就不能用上面的方法获取文件,而是通过下面的方法。(注意参数是MultipartHttpServletRequest类型,而不是HttpServletRequest类型)

@RequestMapping(value="uploadFile", method=RequestMethod.POST)
	public @ResponseBody String uploadFile(MultipartHttpServletRequest request) {
		System.out.println("***** uploadFile *****");
		
		MultiValueMap<String, MultipartFile> map = request.getMultiFileMap();
		Set<String> set = map.keySet();
		Iterator<String> iter = set.iterator();
		while (iter.hasNext()) {
			List<MultipartFile> list = map.get(iter.next());
			for (MultipartFile multiFile : list) {
				System.out.println(multiFile.getOriginalFilename());
			}
		}
		
		return "complete";
	}

或下面的方法。

@RequestMapping(value="uploadFile", method=RequestMethod.POST)
	public @ResponseBody String uploadFile(
			@RequestParam(value="file1") MultipartFile file1,
			@RequestParam(value="file2") MultipartFile file2,
			@RequestParam(value="file3") MultipartFile file3,
			HttpServletRequest request) {
		System.out.println("***** uploadFile *****");
		
		System.out.println("file1: " + file1.getOriginalFilename());
		System.out.println("file2: " + file2.getOriginalFilename());
		System.out.println("file3: " + file3.getOriginalFilename());
		
		return "complete";
	}
(注意:@RequestParm(value=<elm_name>)里的<elm_name>是对应html里的name属性,而不是id属性。如:<input type="file" name="file1">)

原因是,在DispatcherServlet里,doDispatch方法会首先检查Spring有没有加载任何MultipartResolver。(就是配置文件里的CommonMultipartResolver了)。

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
		HttpServletRequest processedRequest = request;
		HandlerExecutionChain mappedHandler = null;
		boolean multipartRequestParsed = false;

		WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

		try {
			ModelAndView mv = null;
			Exception dispatchException = null;

			try {
				processedRequest = <span style="color:#FF0000;"><strong>checkMultipart</strong></span>(request);
				multipartRequestParsed = (processedRequest != request);
                                ...
如果有,并且这个request是一个multipart request,就会调用resolveMultipart方法,把request里的multipart files parse出来(调用ServletFileUpload.parseRequest(request)),放在一个MultipartHttpServletRequest对象里,并返回这个对象。

protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException {
		<strong><span style="color:#FF0000;">if (this.multipartResolver != null && this.multipartResolver.isMultipart(request))</span></strong> {
			if (request instanceof MultipartHttpServletRequest) {
				logger.debug("Request is already a MultipartHttpServletRequest - if not in a forward, " +
						"this typically results from an additional MultipartFilter in web.xml");
			}
			else if (request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) instanceof MultipartException) {
				logger.debug("Multipart resolution failed for current request before - " +
						"skipping re-resolution for undisturbed error rendering");
			}
			else {
				return <strong><span style="color:#FF0000;">this.multipartResolver.resolveMultipart(request);</span></strong>
			}
		}
		// If not returned before: return original request.
		return request;
	}

由于HttpServletRequest在这里经过一次parseRequest(request)操作,所以在Controller方法里不能再通过这种方法拿出multipart file了。而只能传入一个MultipartHttpServletRequest对象,从这个对象里拿出multipart file。


获取上传进度:

因为CommonMultipartResolver没有帮我们添加监听器,如果要获取上传进度,就需要自己扩展这个类。重写parseRequest()方法,在里面添加监听器。

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.listener.FileUploadProgressListener;

public class CustomMultipartResolver extends CommonsMultipartResolver {

	/**
	 * 重写parseRequest方法,在parseRequest()之前添加监听器
	 */
	@Override
	protected MultipartParsingResult parseRequest(HttpServletRequest request) throws MultipartException {
		String encoding = determineEncoding(request);
		FileUpload fileUpload = prepareFileUpload(encoding);
		
		// 在这里添加监听器,其他照抄CommonsMultipartResolver.parseRequest(HttpServletRequest request)
		fileUpload.setProgressListener(new FileUploadProgressListener(request.getSession()));
		
		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);
		}
	}

}

然后在Spring里配置这个扩展的类,代替CommonMultipartResulver。

    <!-- 上传文件拦截,设置最大上传文件大小 1G --> 
    <bean id="multipartResolver" class="com.interceptor.CustomMultipartResolver">
        <property name="maxUploadSize" value="1073741824"/>
    </bean>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值