`

SpringMVC之表单提交===②===单文件上传表单

阅读更多

前文说到springMVC映射普通表单的开发方法,接下来讨论如何使用springmvc上传单个文件。

 

springmvc对form表单的支持已经很成熟,仅仅两步:

  1. 配置支持文件上传的bean:org.springframework.web.multipart.commons.CommonsMultipartResolver

      同时设置文件编码、单次提交表单上传文件最大字节数、以及写文件时使用的缓冲区大小
  2. 开发处理:handler[org.hy.ssm.web.controller.FormController.uploadOne(MultipartFile)]
     
    	/**
    	 * @Title: uploadOne
    	 * @Description: 单文件上传
    	 * @param file
    	 * @return ModelMap
    	 */
    	@RequestMapping("/uploadOne")
    	@ResponseBody
    	public ModelMap uploadOne(MultipartFile file) {
    		final String UPLOAD_DIR = "/upload/";
    		final String KEY_OF_ORIGINAL_FILE_NAME = "origFileName";
    		final String KEY_OF_FILE_URL = "fileUrl";
    		final String KEY_OF_FILE_SUFFIX = "fileSuffix";
    
    		boolean flag = false;
    		String message = null;
    		Map<String, String> data = Maps.newHashMap();
    
    		// 原文件名(通常用于下载展示)
    		String originalFilename = file.getOriginalFilename();
    		data.put(KEY_OF_ORIGINAL_FILE_NAME, originalFilename);
    
    		// 文件类型(后缀)
    		String suffix = FileUtil.getSuffix(originalFilename);
    		data.put(KEY_OF_FILE_SUFFIX, suffix);
    
    		// 目标文件名(通常情况需要重命名, 防止同名文件覆盖)
    		String fileName = String.valueOf(System.currentTimeMillis()) + suffix;
    		String fileUrl = (UPLOAD_DIR + fileName);
    		data.put(KEY_OF_FILE_URL, fileUrl);
    
    		try {
    			File dest = WebUtil.getFile(fileUrl);
    			file.transferTo(dest);
    			flag = true;
    		} catch (Exception e) {
    			flag = false;
    			message = "";
    			LOGGER.warn(message + " : " + e.getMessage(), e);
    		}
    
    		return WebUtil.getModelMap(flag, data, message);
    	}
    
     

接下来验证结果是否正确:

 

  • 正常验证

     

     
  • 非法验证,文件大小超出。当前测试数据70+MB
    org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size of 32505856 bytes exceeded; nested exception is org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (79882924) exceeds the configured maximum (32505856)
    	at org.springframework.web.multipart.commons.CommonsMultipartResolver.parseRequest(CommonsMultipartResolver.java:160)
    	at org.springframework.web.multipart.commons.CommonsMultipartResolver.resolveMultipart(CommonsMultipartResolver.java:139)
    	at org.springframework.web.servlet.DispatcherServlet.checkMultipart(DispatcherServlet.java:1020)
    	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:883)
    	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
    	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
    	at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:789)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
    	at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
    	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
    	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
    	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
    	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1074)
    	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
    	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    	at java.lang.Thread.run(Thread.java:722)
    Caused by: org.apache.commons.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (79882924) exceeds the configured maximum (32505856)
    	at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.<init>(FileUploadBase.java:937)
    	at org.apache.commons.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:331)
    	at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:351)
    	at org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:126)
    	at org.springframework.web.multipart.commons.CommonsMultipartResolver.parseRequest(CommonsMultipartResolver.java:156)
    	... 28 more
     由错误也可定位出,#multipartResolver.maxUploadSize 是用来定位单次表单提交时,文件的限定大小

到此,单文件上传已经搞定。是不是很简单呢?当然了还有稍微原始的方法,通过 org.apache.commons.fileupload.servlet.ServletFileUpload 也能实现文件上传的功能,在此不做详解。大致步骤如下:

  1. 获取工厂 DiskFileItemFactory
  2. 通过工厂获取上传组件 ServletFileUpload
  3. 解析请求获取表单项
  4. 判断表单项类型
  5. 解析表单项
	/**
	 * @Title: uploadByFileUpload
	 * @Description: 使用Commons.FileUpload上传文件
	 */
	@RequestMapping("/uploadByFileUpload")
	public void uploadByFileUpload() {
		final String UPLOAD_DIR = "upload/";
		final String basePath = WebUtil.getBaseFilPath();

		HttpServletRequest request = WebUtil.getRequest();
		try {
			// 防止中文名乱码
			request.setCharacterEncoding("utf-8");

			// 1. 获取工厂 DiskFileItemFactory
			DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();
			// 缓存区目录
			fileItemFactory.setRepository(new File(basePath + "tmp/"));
			// 缓存区大小
			fileItemFactory.setSizeThreshold(1024 * 6);

			// 2. 通过工厂获取上传组件 ServletFileUpload
			ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory);
			// 设置文件的大小为2M
			servletFileUpload.setSizeMax(1024 * 1024 * 2);
			// 防止中文乱码(文件名)
			servletFileUpload.setHeaderEncoding("UTF-8");

			// 3. 解析请求获取表单项
			@SuppressWarnings("unchecked")
			List<FileItem> items = servletFileUpload.parseRequest(request);

			// 4. 判断表单项类型
			for (FileItem item : items) {

				// 5. 解析表单项
				// 表单项名称
				String fieldName = item.getFieldName();
				if (item.isFormField()) {
					// 普通表单项处理
					String name = fieldName;
					String value = item.getString("UTF-8");
					System.out.println(name + ":" + value);

				} else {
					// 文件表单项
					// 获取文件名
					String originalFileName = item.getName();
					String suffix = FileUtil.getSuffix(originalFileName);
					String newFileName = String.valueOf(System.currentTimeMillis());

					// 写入文件
					String fileName = File.separator + newFileName + suffix;
					File newFile = FileUtil.createQuietly(basePath + UPLOAD_DIR + fileName);
					item.write(newFile);
					item.delete();
				}
			}

		} catch (Exception e) {
			LOGGER.warn(e.getMessage(), e);
		}
	}

 

注意:如果使用上面的方式获取上传文件,需要停止 springmvc 的文件解析机制,否则将不能获取数据 !!



 

源码下载:ssmFU.zip

  • 大小: 64.4 KB
  • 大小: 71 KB
  • 大小: 24.1 KB
  • 大小: 56.3 KB
0
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics