`

Spring uploadFile

阅读更多

  先让我们来看一段摘自《Spring 2.5 Reference 中文版》(http://www.redsaga.com/spring_ref/2.5/spring-reference.pdf)的一段关于FileUpload的开场描述:
  "Spring支持web应用中的分段文件上传。这种支持是由即插即用的MultipartResolver来实现。这些解析器都定义在org.springframework.web.multipart包里。Sprig提供了现成的MultipartResolver可以支持Commons FileUpload(http://jakarta.apache.org/commons/fileupload)和COS FileUpload(http://www.servlets.ocm/cos)。"

是的,Spring通过配置一个分段上传解析器来完成对文件上传的解析和封装工作,那么Spring是如何完成这一工作的呢:

首先,DispatcherServlet必须找到一个文件上传解析器的实例,使用这个实例来检查本次请求的HttpServletRequest是否是一个分段文件上传的Request,通过下面的Spring 源码可以看到,首先必须保证有一个MultipartResolver的实例,并且由该类的Resolver的isMultipart方法来验证,本次Request是否为文件上传的Request.如果以上条件都满足,那么Spring将其转换为一个继承自HttpServletRequest的MultipartHttpServletRequest返回,这样在你的Controller中就可以使用这个经过转换的request,从中取到MultipartFile信息。

Java代码 复制代码
  1. protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException {   
  2.     if (this.multipartResolver != null && this.multipartResolver.isMultipart(request)) {   
  3.         if (request instanceof MultipartHttpServletRequest) {   
  4.             logger.debug("Request is already a MultipartHttpServletRequest - if not in a forward, " +   
  5.                     "this typically results from an additional MultipartFilter in web.xml");   
  6.         }   
  7.         else {   
  8.             return this.multipartResolver.resolveMultipart(request);   
  9.         }   
  10.     }   
  11.     // If not returned before: return original request.   
  12.     return request;   
  13. }  
	protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException {
		if (this.multipartResolver != null && this.multipartResolver.isMultipart(request)) {
			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 {
				return this.multipartResolver.resolveMultipart(request);
			}
		}
		// If not returned before: return original request.
		return request;
	}


由以上分析可以看出,我们必须配置一个MultipartResolver,在这里我们使用支持Commons FileUpload的CommonsMultipartResolver:

Java代码 复制代码
  1. <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" p:defaultEncoding="utf-8"/>  
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" p:defaultEncoding="utf-8"/>


而且我们可以在该Resolver中定义文件上传的最大长度:

Java代码 复制代码
  1. <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" p:defaultEncoding="utf-8" p:maxUploadSize="100000"/>  
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver" p:defaultEncoding="utf-8" p:maxUploadSize="100000"/>


当用户选择的上传文件大于maxUploadSize值的时候,commons fileupload会抛出一个异常MaxUploadSizeExceededException表示用户上传的文件超出了最大限制。

当然,我们可以通过Spring MVC中的ExceptionResolver来针对该异常定义一个显示错误的View,但针对有可能存在的多个文件上传Controller中都会发生文件大小超长这个异常的情况,除了我们自定义一个粒度更细的ExceptionResolver,我们还可以把上传文件合法性判断挪到用户自己的Controller中来做。而且我个人更偏向于后一种做法。

除了Spring Configuration之外,我们还需要准备一个页面上传的jsp文件供View视图使用:

Java代码 复制代码
  1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
  2.     pageEncoding="UTF-8"%>   
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">   
  4.   
  5. <html>   
  6.     <head>   
  7.         <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">   
  8.         <title>Insert title here</title>   
  9.     </head>   
  10.        
  11.     <body style="text-align:left">   
  12.         <% if(request.getAttribute("success") != null) {%>   
  13.             Upload Successfully!!!<br/>   
  14.         <% }%>   
  15.         <form id="loginform" name="loginform" method="POST" enctype="multipart/form-data">   
  16.             <table width="100%" border="0" cellspacing="0" cellpadding="0">   
  17.                 <tr>   
  18.                     <td height="30" align="right">Choose File</td>   
  19.                     <td align="left">   
  20.                         <input name="imageFile" type="file"/>   
  21.                     </td>   
  22.                 </tr>   
  23.                 <tr>   
  24.                     <td align="center" colspan="2">   
  25.                         <input type="submit" value="submit" name="submit" />   
  26.                     </td>   
  27.                 </tr>   
  28.             </table>   
  29.         </form>   
  30.     </body>   
  31. </html>  
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<title>Insert title here</title>
	</head>
	
	<body style="text-align:left">
		<% if(request.getAttribute("success") != null) {%>
			Upload Successfully!!!<br/>
		<% }%>
		<form id="loginform" name="loginform" method="POST" enctype="multipart/form-data">
			<table width="100%" border="0" cellspacing="0" cellpadding="0">
				<tr>
					<td height="30" align="right">Choose File</td>
					<td align="left">
						<input name="imageFile" type="file"/>
					</td>
				</tr>
				<tr>
					<td align="center" colspan="2">
						<input type="submit" value="submit" name="submit" />
					</td>
				</tr>
			</table>
		</form>
	</body>
</html>


注意:在文件上传Form表单中,一定要将enctype设置为"multipart/form-data"因为只有这样才能使Spring知道这是一个文件上传的请求。

细心的读者也许能发现Form表单中action为默认值也就是说post到和上传页面同样的URL,因此我们定义了一个Controller分别来处理这个请求的GET和POST请求。下面让我们来看看这个Controller:

1.我们通过@Controller声明这个类为Spring组件,告知Spring容器在初始化的时候需要加载该类实例到Spring Context Container中。
2.通过@RequestMapping("/sec_upload.do")将sec_upload.do的请求指向该Controller处理。

Java代码 复制代码
  1. @Controller  
  2. @RequestMapping("/sec_upload.do")   
  3. public class UploadController {   
  4.     //...   
  5. }  
@Controller
@RequestMapping("/sec_upload.do")
public class UploadController {
	//...
}


3.定义一个处理GET请求的方法,该方法简单的将选择文件Form表单页展现给用户:

Java代码 复制代码
  1. @RequestMapping(method = RequestMethod.GET)   
  2.     public String handleUploadShow() {   
  3.         return "uploadView";   
  4.     }  
@RequestMapping(method = RequestMethod.GET)
	public String handleUploadShow() {
		return "uploadView";
	}


4.定义一个处理POST请求的方法,该方法进行用户文件上传处理:

Java代码 复制代码
  1. @RequestMapping(method = RequestMethod.POST)   
  2.     public String handleUploadProcess(   
  3.             @RequestParam("imageFile") MultipartFile file, Model model)   
  4.             throws Exception {   
  5.         //具体的业务逻辑操作。。。   
  6.         model.addAttribute("success""true");   
  7.         return "uploadView";   
  8.     }  
@RequestMapping(method = RequestMethod.POST)
	public String handleUploadProcess(
			@RequestParam("imageFile") MultipartFile file, Model model)
			throws Exception {
		//具体的业务逻辑操作。。。
		model.addAttribute("success", "true");
		return "uploadView";
	}


通过@RequestParam("imageFile")注解,Spring会将request请求中的imageFile的文件信息自动绑定到MultipartFile对象。

上面的Controller方法解决的文件绑定的问题,但假设我们的Form表单中除了文件选择框还有其他一些用户填写的信息,那么我们怎么处理呢?仿照上面的方法,我们可以为多个参数提供多个@RequestParam注解来完成数据绑定工作,但我们也可以通过MultipartHttpServletRequest对象来获取这些信息,因为在DispatcherServlet中Spring已经将一个普通的HttpServletRequest转换为了一个MultipartHttpServletRequest:

Java代码 复制代码
  1. @RequestMapping(method = RequestMethod.POST)   
  2. public String handleAnotherUploadProcess(   
  3.         MultipartHttpServletRequest request, Model model) throws Exception {   
  4.     MultipartFile file = request.getFile("imageFile");   
  5.     //request.getParameter("xxx");   
  6.     //request.getContentType();   
  7.     //request.getContentLength();   
  8.     //some other processing...   
  9.     model.addAttribute("success""true");   
  10.     return "uploadView";   
  11. }  
	@RequestMapping(method = RequestMethod.POST)
	public String handleAnotherUploadProcess(
			MultipartHttpServletRequest request, Model model) throws Exception {
		MultipartFile file = request.getFile("imageFile");
		//request.getParameter("xxx");
		//request.getContentType();
		//request.getContentLength();
		//some other processing...
		model.addAttribute("success", "true");
		return "uploadView";
	}



这种方式还是需要我们不断的通过request.getParameter("xxx")方式来获得参数,了解Spring MVC的同学可能想到了,使用CommandObject绑定-回答正确。假设我们定义了一个POJO对象:

Java代码 复制代码
  1. public class BoUploadFile {   
  2.     private MultipartFile imageFile;   
  3.   
  4.     public MultipartFile getImageFile() {   
  5.         return imageFile;   
  6.     }   
  7.   
  8.     public void setImageFile(MultipartFile imageFile) {   
  9.         this.imageFile = imageFile;   
  10.     }   
  11.   
  12.     private String name;   
  13.   
  14.     public String getName() {   
  15.         return name;   
  16.     }   
  17.   
  18.     public void setName(String name) {   
  19.         this.name = name;   
  20.     }   
  21. }  
public class BoUploadFile {
	private MultipartFile imageFile;

	public MultipartFile getImageFile() {
		return imageFile;
	}

	public void setImageFile(MultipartFile imageFile) {
		this.imageFile = imageFile;
	}

	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}


这个对象中不仅包括需要封装的上传文件信息,还包括其他一些用户输入的普通信息。那么有了这个封装对象,我们的Controller可以变成如下的样子:

Java代码 复制代码
  1. @RequestMapping(method = RequestMethod.POST)   
  2. public String handleThirdUploadProcess(BoUploadFile uploadFile, Model model) throws Exception{   
  3.     MultipartFile file = uploadFile.getImageFile();   
  4.     //这里你可以通过uploadFile.getName()...等等获取用户输入的其他普通信息了。   
  5.     model.addAttribute("success""true");   
  6.     return "uploadView";   
  7. }  
	@RequestMapping(method = RequestMethod.POST)
	public String handleThirdUploadProcess(BoUploadFile uploadFile, Model model) throws Exception{
		MultipartFile file = uploadFile.getImageFile();
		//这里你可以通过uploadFile.getName()...等等获取用户输入的其他普通信息了。
		model.addAttribute("success", "true");
		return "uploadView";
	}



5.自定义一个文件验证类,来验证文件的合法性。

Java代码 复制代码
  1. /**  
  2.  * 用户文件上传验证类  
  3.  *   
  4.  * @author Jacky Lau created at 2008-8-27  
  5.  * @since 1.0  
  6.  * @version 1.0  
  7.  */  
  8. public class MultipartFileValidator {   
  9.   
  10.     private final static long MAX_SIZE = 1024 * 1024;   
  11.   
  12.     /**  
  13.      * 文件大小上限  
  14.      */  
  15.     private long maxSize = MAX_SIZE;   
  16.   
  17.     /**  
  18.      * 可接受的文件content-type  
  19.      */  
  20.     private String[] allowedContentTypes;   
  21.   
  22.     @PostConstruct  
  23.     public void afterPropertiesSet() {   
  24.         Assert   
  25.                 .notEmpty(allowedContentTypes,   
  26.                         "The content types allowed to be uploaded must contain one at least!");   
  27.     }   
  28.   
  29.     /**  
  30.      * 验证上传文件是否合法,如果不合法那么会抛出异常  
  31.      *   
  32.      * @param file  
  33.      *            用户上传的文件封装类  
  34.      */  
  35.     public void validate(MultipartFile file) {   
  36.         Assert.notNull(file, "The multipart file is null!");   
  37.         if (file.getSize() > maxSize)   
  38.             throw new FileOutOfMaxLengthException("error.upload.outmaxlen",   
  39.                     new Object[] { maxSize },   
  40.                     "The file uploaded is out of max file size!");   
  41.         if (!ArrayUtils.contains(allowedContentTypes, file.getContentType()))   
  42.             throw new ContentTypeNotSupportException("error.upload.content.notsupported"null,   
  43.                     "The content type '"+file .getContentType()+"' is not a valid content type !");   
  44.     }   
  45.   
  46.     /**  
  47.      * 设置文件上传大小上限  
  48.      *   
  49.      * @param maxSize  
  50.      *            文件上传大小上限  
  51.      */  
  52.     public void setMaxSize(long maxSize) {   
  53.         this.maxSize = maxSize;   
  54.     }   
  55.   
  56.     /**  
  57.      * 设置可接受的文件content-type数组  
  58.      *   
  59.      * @param allowedContentTypes  
  60.      *            可接受的文件content-type数组  
  61.      */  
  62.     public void setAllowedContentTypes(String[] allowedContentTypes) {   
  63.         this.allowedContentTypes = allowedContentTypes;   
  64.     }   
  65.   
  66. }  
/**
 * 用户文件上传验证类
 * 
 * @author Jacky Lau created at 2008-8-27
 * @since 1.0
 * @version 1.0
 */
public class MultipartFileValidator {

	private final static long MAX_SIZE = 1024 * 1024;

	/**
	 * 文件大小上限
	 */
	private long maxSize = MAX_SIZE;

	/**
	 * 可接受的文件content-type
	 */
	private String[] allowedContentTypes;

	@PostConstruct
	public void afterPropertiesSet() {
		Assert
				.notEmpty(allowedContentTypes,
						"The content types allowed to be uploaded must contain one at least!");
	}

	/**
	 * 验证上传文件是否合法,如果不合法那么会抛出异常
	 * 
	 * @param file
	 *            用户上传的文件封装类
	 */
	public void validate(MultipartFile file) {
		Assert.notNull(file, "The multipart file is null!");
		if (file.getSize() > maxSize)
			throw new FileOutOfMaxLengthException("error.upload.outmaxlen",
					new Object[] { maxSize },
					"The file uploaded is out of max file size!");
		if (!ArrayUtils.contains(allowedContentTypes, file.getContentType()))
			throw new ContentTypeNotSupportException("error.upload.content.notsupported", null,
					"The content type '"+file .getContentType()+"' is not a valid content type !");
	}

	/**
	 * 设置文件上传大小上限
	 * 
	 * @param maxSize
	 *            文件上传大小上限
	 */
	public void setMaxSize(long maxSize) {
		this.maxSize = maxSize;
	}

	/**
	 * 设置可接受的文件content-type数组
	 * 
	 * @param allowedContentTypes
	 *            可接受的文件content-type数组
	 */
	public void setAllowedContentTypes(String[] allowedContentTypes) {
		this.allowedContentTypes = allowedContentTypes;
	}

}



这样我们可以通过这个validator判断上传的文件是否超出了最大限制,文件格式是否正确等判断。我们可以通过配置文件配置该验证器,在这里为了方便起见在类中我用以下方式来初始化该验证器:

Java代码 复制代码
  1. private MultipartFileValidator validator;   
  2.   
  3. @PostConstruct  
  4. public void init() {   
  5.     validator = new MultipartFileValidator();   
  6.     validator.setAllowedContentTypes(new String[] { "image/jpeg",   
  7.             "image/pjpeg" });   
  8. }  
	private MultipartFileValidator validator;

	@PostConstruct
	public void init() {
		validator = new MultipartFileValidator();
		validator.setAllowedContentTypes(new String[] { "image/jpeg",
				"image/pjpeg" });
	}



至此,我们已经完成了文件上传的开发,可以看出这和普通的Controller开发没有任何区别,简单而且灵活。以下是该Controller的全部代码:

Java代码 复制代码
  1. @Controller  
  2. @RequestMapping("/sec_upload.do")   
  3. public class UploadController {   
  4.   
  5.     private MultipartFileValidator validator;   
  6.   
  7.     @PostConstruct  
  8.     public void init() {   
  9.         validator = new MultipartFileValidator();   
  10.         validator.setAllowedContentTypes(new String[] { "image/jpeg",   
  11.                 "image/pjpeg" });   
  12.     }   
  13.   
  14.     @RequestMapping(method = RequestMethod.GET)   
  15.     public String handleUploadShow() {   
  16.         return "uploadView";   
  17.     }   
  18.   
  19.     @RequestMapping(method = RequestMethod.POST)   
  20.     public String handleUploadProcess(   
  21.             @RequestParam("imageFile") MultipartFile file, Model model)   
  22.             throws Exception {   
  23.         validator.validate(file);   
  24.         String path = "d:\\temp\\ftp\\" + file.getOriginalFilename();   
  25.         String resizePath = "d:\\temp\\ftp\\resize\\"  
  26.                 + file.getOriginalFilename();   
  27.         FileHelper.save(path, file.getBytes());   
  28.         if (ImageHelper.isJpg(ImageHelper.getImageType(path)))   
  29.             ImageHelper.resizeJPG(path, resizePath, 120118);   
  30.         model.addAttribute("success""true");   
  31.         return "uploadView";   
  32.     }   
  33. }  
@Controller
@RequestMapping("/sec_upload.do")
public class UploadController {

	private MultipartFileValidator validator;

	@PostConstruct
	public void init() {
		validator = new MultipartFileValidator();
		validator.setAllowedContentTypes(new String[] { "image/jpeg",
				"image/pjpeg" });
	}

	@RequestMapping(method = RequestMethod.GET)
	public String handleUploadShow() {
		return "uploadView";
	}

	@RequestMapping(method = RequestMethod.POST)
	public String handleUploadProcess(
			@RequestParam("imageFile") MultipartFile file, Model model)
			throws Exception {
		validator.validate(file);
		String path = "d:\\temp\\ftp\\" + file.getOriginalFilename();
		String resizePath = "d:\\temp\\ftp\\resize\\"
				+ file.getOriginalFilename();
		FileHelper.save(path, file.getBytes());
		if (ImageHelper.isJpg(ImageHelper.getImageType(path)))
			ImageHelper.resizeJPG(path, resizePath, 120, 118);
		model.addAttribute("success", "true");
		return "uploadView";
	}
}



在以后的文章中,我会对Spring进行上传文件特殊处理做一些探究,比如用户上传一个csv的通讯录文件,那么通过Spring的属性编辑器一个custom的Editor来进行数据转换,可以将CSV中的信息转换成其他你所需要的信息:比如从CSV文件中抽取邮件地址放到一个字符串数组中,让你可以进行后续的业务逻辑操作。。。

 

而在本文中让我们来讨论一下文件上传的另外一种情况,例如一个支持导入你的本地通讯录列表的Web Mail系统。那么这个Mail System可能不仅仅希望你上传的通讯录文件作为一个副本保存在服务器端,他还希望更进一步的了解你上传通讯录文件的内容,以便能够将这些内容添加到你的Web Mail通讯录中。好的,我们了解了这样一个需求,就让我们来看看Spring MVC是如何做到的。

首先,让我们来看一段Spring 2.5 Reference中文版中的话(详情请参考http://www.redsaga.com/spring_ref/2.5/html/mvc.html#mvc-multipart-forms):

引用
和其它不能自动转为字符串类型或者基本类型(primitive type)的属性一样,为了将上传的二进制数据存成bean的属性,必须通过ServletRequestDatabinder注册一个属性编辑器。 Spring中内置了几个这样的编辑器,它们可以处理文件,然后将结果存成bean的属性。 比如,StringMultipartEditor可以将文件转换成一个字符串(使用用户声明的字符集)。ByteArrayMultipartEditor可以以将文件转换为byte数组。 他们的功能和CustomDateEditor相似。



也就是说,我们可以通过一个特定的属性编辑器来讲得到的二进制数据转换成我们希望的数据类型,比如一个文本字符串或者提取其中的某些属性组成一个字符串列表,比如Email通讯录列表。

为了启用我们的PropertyEditor,那么我们就需要了解另外一个东东-WebDataBinder,通过它去调用PropertyEditor,我们可以将请求数据绑定成我们希望的数据对象。

初始化自定义WebDataBinder的方法有两种(详情请参考http://www.redsaga.com/spring_ref/2.5/html/mvc.html#mvc-ann-webdatabinder):
1.使用@InitBinder注解;

Java代码 复制代码
  1. @Controller  
  2. ublic class MyFormController {   
  3.   
  4.    @InitBinder  
  5.    public void initBinder(WebDataBinder binder) {   
  6.        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");   
  7.        dateFormat.setLenient(false);   
  8.        binder.registerCustomEditor(Date.classnew CustomDateEditor(dateFormat, false));   
  9.    }   
  10.   
  11.    // ...   
  @Controller
	public class MyFormController {

	    @InitBinder
	    public void initBinder(WebDataBinder binder) {
	        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
	        dateFormat.setLenient(false);
	        binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
	    }

	    // ...
	}



2.在配置文件中配置

Java代码 复制代码
  1. <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">   
  2.     <property name="cacheSeconds" value="0" />   
  3.     <property name="webBindingInitializer">   
  4.         <bean class="org.springframework.samples.petclinic.web.ClinicBindingInitializer" />   
  5.     </property>   
  6. </bean>  
	<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
	    <property name="cacheSeconds" value="0" />
	    <property name="webBindingInitializer">
	        <bean class="org.springframework.samples.petclinic.web.ClinicBindingInitializer" />
	    </property>
	</bean>



让我们继续导入通讯录列表的例子,首先让我们准备一个CSV邮件通讯录列表文件contacts.csv:

Java代码 复制代码
  1. 名,姓,全名,昵称,邮箱地址   
  2. Jacky,Lau,Jacky Lau,,jacky@gmail.com   
  3. Grace,Fox,Grace Fox,,grace@gmail.com   
  4. Tom,Hanks,Tom Hanks,,tom@gmail.com   
  5. Charly,White,Charly White,,charly@gmail.com  
名,姓,全名,昵称,邮箱地址
Jacky,Lau,Jacky Lau,,jacky@gmail.com
Grace,Fox,Grace Fox,,grace@gmail.com
Tom,Hanks,Tom Hanks,,tom@gmail.com
Charly,White,Charly White,,charly@gmail.com



我们还需要一个类来表示好友邮件信息-Email.class:

Java代码 复制代码
  1. public class Email {   
  2.     private String name;   
  3.   
  4.     private String email;   
  5.   
  6.     public String getName() {   
  7.         return name;   
  8.     }   
  9.   
  10.     public void setName(String name) {   
  11.         this.name = name;   
  12.     }   
  13.   
  14.     public String getEmail() {   
  15.         return email;   
  16.     }   
  17.   
  18.     public void setEmail(String email) {   
  19.         this.email = email;   
  20.     }   
  21. }  
public class Email {
	private String name;

	private String email;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}
}



接下来我们来准备一个自定义的Property Editor: CustomEmailDataEditor

Java代码 复制代码
  1. public class CustomEmailDataEditor extends PropertyEditorSupport {   
  2.   
  3.     public void setValue(Object value) {   
  4.         if (value instanceof MultipartFile) {//处理上传文件,此处默认上传的是格式正确的CSV文件   
  5.             MultipartFile multipartFile = (MultipartFile) value;   
  6.             System.out.println(multipartFile.getContentType());//打印Content-Type   
  7.             try {   
  8.                 //使用第三方开源类库OpenCSV来读取CSV文件   
  9.                 CSVReader reader = new CSVReader(new InputStreamReader(   
  10.                         multipartFile.getInputStream()));   
  11.                 String[] nextLine;   
  12.                 // 去除第一行header信息   
  13.                 reader.readNext();   
  14.   
  15.                 List<Email> emails = new ArrayList<Email>();   
  16.                 while ((nextLine = reader.readNext()) != null) {   
  17.                     Email email = new Email();   
  18.                     email.setName(nextLine[2]);   
  19.                     email.setEmail(nextLine[4]);   
  20.                     emails.add(email);   
  21.                 }   
  22.                    
  23.                 //绑定数据列表   
  24.                 super.setValue(emails);   
  25.             } catch (IOException ex) {   
  26.                 throw new IllegalArgumentException(   
  27.                         "Cannot read contents of multipart file: "  
  28.                                 + ex.getMessage());   
  29.             }   
  30.         } else if (value instanceof byte[]) {   
  31.             super.setValue(value);   
  32.         } else {   
  33.             super.setValue(value != null ? value.toString().getBytes() : nu</spa
    分享到:
    评论

相关推荐

    springcloud处理文件上传

    在分布式系统中,Spring Cloud作为一个强大的微服务框架,提供了丰富的组件来解决各种问题。本话题主要探讨如何在Spring Cloud环境中处理文件上传,特别是在结合Feign和Zuul这两个组件时的实现方法。Feign是Spring ...

    springboot-uploadfile.zip

    在本项目"springboot-uploadfile.zip"中,我们聚焦于使用Spring Boot 2.0来构建RESTful API,实现文件的上传与下载功能。这个实战课程的源码提供了清晰的指导,帮助开发者理解如何在实际应用中处理这些常见的Web操作...

    SpringCloud接收文件

    public ResponseEntity&lt;?&gt; uploadFile(@RequestParam("file") MultipartFile file) { // 文件处理逻辑 } ``` `MultipartFile`对象包含了文件名、类型、大小等信息,可以直接存入数据库或者文件系统。 3. **...

    springboot uploadFile

    综上所述,"springboot uploadFile"涉及的主要知识点包括:Spring Boot与Spring MVC的集成、文件上传原理、`MultipartFile`的使用、配置文件大小限制、文件存储策略、错误处理和安全性考量。通过理解这些概念,...

    uploadFile.zip

    本压缩包"uploadFile.zip"包含了一个简单的Spring Boot项目,演示了如何实现文件上传的功能。下面将详细解释这个模型中涉及的关键知识点。 1. **Spring Boot 2.0基础**: Spring Boot 2.0是基于Spring Framework 5...

    uploadfile(包含实例)

    "uploadfile(包含实例)"这个标题暗示了我们将会探讨一个关于文件上传的实际示例,而"JAVA上传"标签进一步确认了我们将专注于Java语言中的相关技术。在这个场景下,我们通常会使用Servlet、HTTP多部分请求(Multipart...

    Java Spring Boot应用程序中实现文件上传和下载功能

    public String uploadFile(@RequestParam("file") MultipartFile file) { try { // 检查文件是否存在 if (file.isEmpty()) { return "文件为空"; } // 文件保存路径 String filePath = "path/to/upload/...

    Struts2框架整合Spring框架在文件上传下载中的应用基于HT T P 传输协议, 采用Struts2 框架整合Spring 框架技术对Web 中文件的上传下载进

    ### Struts2框架整合Spring框架在文件上传下载中的应用 #### 一、引言 随着互联网技术的迅速发展,Web应用程序的功能越来越丰富,文件的上传下载功能已成为许多Web应用不可或缺的一部分。例如,在博客、电子邮件...

    Spring boot整合MinIO客户端实现文件管理

    MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和...Spring boot整合MinIO客户端实现文件管理

    简单易行:Spring中操作LOB字段案例

    在Spring框架中,LOB(Large Object)字段通常用于存储大数据,如BLOB(Binary Large Object)用于二进制数据,如图片或文档,CLOB(Character Large Object)用于字符数据,如长文本。本篇文章将深入探讨如何在...

    JAVA 使用uploadFile实现文件上传服务器

    文件上传通常发生在Web服务器端,所以你需要创建一个Servlet或者Spring MVC的Controller来接收文件。下面是一个简单的Servlet示例: ```java import org.apache.commons.fileupload.FileItem; import org....

    spring mvc 上传文件显示进度

    public ResponseEntity&lt;String&gt; uploadFile(@RequestParam("file") MultipartFile file, HttpServletRequest request) { // 创建进度监听器 ProgressListener listener = new ProgressListener() { @Override ...

    uploadfile_大文件上传_springboot_webupload_源码

    本项目"uploadfile_大文件上传_springboot_webupload_源码"旨在演示如何结合WebUpload和Spring Boot实现高效的大文件上传功能。 首先,我们要理解Spring Boot中的MultipartFile接口。这是Spring MVC框架为处理上传...

    spring cloud feign实现远程调用服务传输文件的方法

    Spring Cloud Feign 实现远程调用服务传输文件的方法 在微服务架构中,服务之间的调用和文件传输是非常常见的场景。Spring Cloud Feign 是一个基于 Java 的声明式 RESTful 客户端,提供了一种简单、可靠的方式来...

    hassian+spring +fileupload

    在这个例子中,我们关注的是如何结合Hessian和Spring框架来实现文件上传。Hessian是一种高效的RPC(远程过程调用)协议,它能够提供轻量级的、跨语言的服务调用,而Spring则是一个广泛使用的Java企业级应用开发框架...

    spring mvc+ajax 导出导入xml文件功能实现和整理

    后端主要由Java代码构成,定义了一个uploadFile方法来处理客户端上传的文件。使用了Apache Commons FileUpload库来解析请求并获取文件内容。首先,创建了一个CommonsMultipartResolver对象,用来解析multipart请求...

    SpringCloud使用Feign文件上传、下载

    SpringCloud使用Feign文件上传、下载 在分布式系统中,文件上传和下载是非常常见的场景。SpringCloud提供了Feign来帮助我们实现文件上传和下载功能。在本文中,我们将详细介绍如何使用SpringCloud和Feign来实现文件...

    从零搭建Spring Boot脚手架整合OSS作为文件服务器的详细教程

    public void uploadFile(String fileName, File file) { PutObjectRequest request = new PutObjectRequest(bucketName, fileName, file); ossClient.putObject(request); } ``` 5. **项目实践** - **获取项目**...

    spring-boot-minio-master.zip

    public void uploadFile(String bucketName, String objectName, File file) { try { minioClient.putObject(bucketName, objectName, file); } catch (Exception e) { // 处理异常 } } // 其他如下载、...

Global site tag (gtag.js) - Google Analytics