在前一篇文章我们通过强大并且易用的Spring MVC中的MultipartResolver简单快速的实现了文件的上传(地址如下:[url]http://dakulaliu.iteye.com/blog/236235[/url])。
而在本文中让我们来讨论一下文件上传的另外一种情况,例如一个支持导入你的本地通讯录列表的Web Mail系统。那么这个Mail System可能不仅仅希望你上传的通讯录文件作为一个副本保存在服务器端,他还希望更进一步的了解你上传通讯录文件的内容,以便能够将这些内容添加到你的Web Mail通讯录中。好的,我们了解了这样一个需求,就让我们来看看Spring MVC是如何做到的。
首先,让我们来看一段Spring 2.5 Reference中文版中的话(详情请参考[url]http://www.redsaga.com/spring_ref/2.5/html/mvc.html#mvc-multipart-forms[/url]):
[quote]和其它不能自动转为字符串类型或者基本类型(primitive type)的属性一样,为了将上传的二进制数据存成bean的属性,必须通过ServletRequestDatabinder注册一个属性编辑器。 Spring中内置了几个这样的编辑器,它们可以处理文件,然后将结果存成bean的属性。 比如,StringMultipartEditor可以将文件转换成一个字符串(使用用户声明的字符集)。ByteArrayMultipartEditor可以以将文件转换为byte数组。 他们的功能和CustomDateEditor相似。[/quote]
也就是说,我们可以通过一个特定的属性编辑器来讲得到的二进制数据转换成我们希望的数据类型,比如一个文本字符串或者提取其中的某些属性组成一个字符串列表,比如Email通讯录列表。
为了启用我们的PropertyEditor,那么我们就需要了解另外一个东东-WebDataBinder,通过它去调用PropertyEditor,我们可以将请求数据绑定成我们希望的数据对象。
初始化自定义WebDataBinder的方法有两种(详情请参考[url]http://www.redsaga.com/spring_ref/2.5/html/mvc.html#mvc-ann-webdatabinde[/url]r):
1.使用@InitBinder注解;
2.在配置文件中配置
让我们继续导入通讯录列表的例子,首先让我们准备一个CSV邮件通讯录列表文件contacts.csv:
我们还需要一个类来表示好友邮件信息-Email.class:
接下来我们来准备一个自定义的Property Editor: CustomEmailDataEditor
在这段代码中使用到了一个开源的第三方类库OpenCSV来读取CSV文件,该类库的下载地址是[url]http://opencsv.sourceforge.net/[/url]
接下来,我们需要将自定义的Property Editor注册。我们通过在Controller类中@InitBinder注解的方式注册:
接下来让我们来看Controller方法:
OK,到这里我们所有的工作已经准备完成,此处忽略了一些Spring MVC @Controller的配置,详情请参考上一篇文章[url]http://dakulaliu.iteye.com/blog/236235[/url],在Eclipse中启动Tomcat 6.0 Server上传刚才我们创建的contacts.csv
文件,完成之后在控制台打印出上传文件的信息:
[quote]application/vnd.ms-excel
Name is Contacts List
Name : Jacky Lau | email : jacky@gmail.com
Name : Grace Fox | email : grace@gmail.com
Name : Tom Hanks | email : tom@gmail.com
Name : Charly White | email : charly@gmail.com[/quote]
好了-搞定-收工!
而在本文中让我们来讨论一下文件上传的另外一种情况,例如一个支持导入你的本地通讯录列表的Web Mail系统。那么这个Mail System可能不仅仅希望你上传的通讯录文件作为一个副本保存在服务器端,他还希望更进一步的了解你上传通讯录文件的内容,以便能够将这些内容添加到你的Web Mail通讯录中。好的,我们了解了这样一个需求,就让我们来看看Spring MVC是如何做到的。
首先,让我们来看一段Spring 2.5 Reference中文版中的话(详情请参考[url]http://www.redsaga.com/spring_ref/2.5/html/mvc.html#mvc-multipart-forms[/url]):
[quote]和其它不能自动转为字符串类型或者基本类型(primitive type)的属性一样,为了将上传的二进制数据存成bean的属性,必须通过ServletRequestDatabinder注册一个属性编辑器。 Spring中内置了几个这样的编辑器,它们可以处理文件,然后将结果存成bean的属性。 比如,StringMultipartEditor可以将文件转换成一个字符串(使用用户声明的字符集)。ByteArrayMultipartEditor可以以将文件转换为byte数组。 他们的功能和CustomDateEditor相似。[/quote]
也就是说,我们可以通过一个特定的属性编辑器来讲得到的二进制数据转换成我们希望的数据类型,比如一个文本字符串或者提取其中的某些属性组成一个字符串列表,比如Email通讯录列表。
为了启用我们的PropertyEditor,那么我们就需要了解另外一个东东-WebDataBinder,通过它去调用PropertyEditor,我们可以将请求数据绑定成我们希望的数据对象。
初始化自定义WebDataBinder的方法有两种(详情请参考[url]http://www.redsaga.com/spring_ref/2.5/html/mvc.html#mvc-ann-webdatabinde[/url]r):
1.使用@InitBinder注解;
@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.在配置文件中配置
<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:
名,姓,全名,昵称,邮箱地址
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:
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
public class CustomEmailDataEditor extends PropertyEditorSupport {
public void setValue(Object value) {
if (value instanceof MultipartFile) {//处理上传文件,此处默认上传的是格式正确的CSV文件
MultipartFile multipartFile = (MultipartFile) value;
System.out.println(multipartFile.getContentType());//打印Content-Type
try {
//使用第三方开源类库OpenCSV来读取CSV文件
CSVReader reader = new CSVReader(new InputStreamReader(
multipartFile.getInputStream()));
String[] nextLine;
// 去除第一行header信息
reader.readNext();
List<Email> emails = new ArrayList<Email>();
while ((nextLine = reader.readNext()) != null) {
Email email = new Email();
email.setName(nextLine[2]);
email.setEmail(nextLine[4]);
emails.add(email);
}
//绑定数据列表
super.setValue(emails);
} catch (IOException ex) {
throw new IllegalArgumentException(
"Cannot read contents of multipart file: "
+ ex.getMessage());
}
} else if (value instanceof byte[]) {
super.setValue(value);
} else {
super.setValue(value != null ? value.toString().getBytes() : null);
}
}
}
在这段代码中使用到了一个开源的第三方类库OpenCSV来读取CSV文件,该类库的下载地址是[url]http://opencsv.sourceforge.net/[/url]
接下来,我们需要将自定义的Property Editor注册。我们通过在Controller类中@InitBinder注解的方式注册:
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(List.class, new CustomEmailDataEditor());
}
接下来让我们来看Controller方法:
@RequestMapping(method = RequestMethod.POST)
public String handleUploadProcess(BoUploadFile upload, Model model)
throws Exception {
System.out.println("Name is " + upload.getName());
for (Email email : upload.getImageFile()) {
System.out.println("Name : " + email.getName() + " | email : "
+ email.getEmail());
}
model.addAttribute("success", "true");
return "uploadView";
}
OK,到这里我们所有的工作已经准备完成,此处忽略了一些Spring MVC @Controller的配置,详情请参考上一篇文章[url]http://dakulaliu.iteye.com/blog/236235[/url],在Eclipse中启动Tomcat 6.0 Server上传刚才我们创建的contacts.csv
文件,完成之后在控制台打印出上传文件的信息:
[quote]application/vnd.ms-excel
Name is Contacts List
Name : Jacky Lau | email : jacky@gmail.com
Name : Grace Fox | email : grace@gmail.com
Name : Tom Hanks | email : tom@gmail.com
Name : Charly White | email : charly@gmail.com[/quote]
好了-搞定-收工!