`
hanqunfeng
  • 浏览: 1538396 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Spring2.5MVC--基于注解的附件上传

阅读更多

Spring支持web应用中的分段文件上传。这种支持是由即插即用的MultipartResolver来实现。

 

在Spring2.0时,Spring提供了两种现成的MultipartResolver

1.Commons FileUpload(http://jakarta.apache.org/commons/fileupload)

2. COS FileUpload(http://www.servlets.com/cos)

 

不过在spring2.5以后,则只支持Commons FileUpload了。

 

那么,在spring2.5基于注解的MVC中如何使用MultipartResolver呢,

下面通过一个例子来说明如何使用CommonsMultipartResolver执行附件上传。

 

首先我们来构建一个web工程,工程结构如下图所示:

 

 

 

关于springMVC的配置这里不再详述,读者可以参看以前的文章。

这里我们只需要在spring-servlet.xml中加入如下内容,用以通知spring加载文件上传处理器:

<!-- 定义文件上传处理器 -->
 <bean id="multipartResolver"
  class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
  p:defaultEncoding="UTF-8" />

 

 

当配置了这个处理器后,spring会对用户请求进行拦截,判断是否为附件上传类型,既enctype="multipart/form-data",如果是,则会对请求流进行处理,将其转换为DefaultMultipartHttpServletRequest对象,该对象封装了附件内容,例如:

 

//取得附件名称列表

Iterator iterator = multipartRequest.getFileNames();

while(iterator.hasNext()){

//循环取出每一个附件 MultipartFile multifile = multipartRequest.getFile((String)iterator.next()); System.out.println(multifile.getOriginalFilename()); }

 

 

来看一个例子:

在页面中有两个上传文本框,如下:

<form action="<%=request.getContextPath() %>/demo/upload.do" enctype="multipart/form-data" method="post">

 file1:<input type="file" name="file1" id="file1" />

<br></br>

 file2:<input type="file" name="file2" id="file2" />

 <br></br>

<button type="submit">submit</button>

 </form>

 

 

注意,这里一定要将form的enctype属性设置为multipart/form-data,否则不能实现附件上传。

 

当选择要上传的文件后,点击submit按钮,controller处理方法如下:

 

@RequestMapping(value = "/demo/upload.do")
 public String handleImport(
   @RequestParam(value = "file1", required = false) MultipartFile file1,
   @RequestParam(value = "file2", required = false) MultipartFile file2,
   Model model) throws IOException {
  List<FileModel> list = new ArrayList<FileModel>();
  if (file1 != null&&StringUtils.hasText(file1.getOriginalFilename())) {
   System.out.println(file1.getOriginalFilename());

   FileModel fileModel1 = new FileModel();
   fileModel1.setName(file1.getOriginalFilename());
   fileModel1.setSize(file1.getSize());
   String path = service.saveFileToServer(file1, ASVE_PATH);
   fileModel1.setPath(path);
   list.add(fileModel1);
  }
  if (file2 != null&&StringUtils.hasText(file2.getOriginalFilename())) {
   System.out.println(file2.getOriginalFilename());

   FileModel fileModel2 = new FileModel();
   fileModel2.setName(file2.getOriginalFilename());
   fileModel2.setSize(file2.getSize());
   String path = service.saveFileToServer(file1, ASVE_PATH);
   fileModel2.setPath(path);
   list.add(fileModel2);

  }
  model.addAttribute("list", list);
  return "demo/list";

 }

 

 说明:

1.@RequestParam(value = "file1", required = false) :将参数中的file1绑定到MultipartFile file1,此时CommonsMultipartResolver已经帮我们把附件内容填充到MultipartFile 中了,这里required = false最好设置为false,除非你确定这个参数一定会传递给controller,否则会抛出参数绑定异常。

2.ASVE_PATH:一个常量,文件保存的路径

3.service.saveFileToServer():该方法将上传文件保存到指定路径。

4.getOriginalFilename():文件名称

5.getSize():文件大小

 

这里说一下saveFileToServer(),该方法将附件保存到指定路径,并返回保存后的文件全路径:

 

public String saveFileToServer(MultipartFile multifile, String path)
   throws IOException {
  // 创建目录
  File dir = new File(path);
  if (!dir.exists()) {
   dir.mkdir();
  }
  // 读取文件流并保持在指定路径
  InputStream inputStream = multifile.getInputStream();
  OutputStream outputStream = new FileOutputStream(path
    + multifile.getOriginalFilename());
  byte[] buffer = multifile.getBytes();
  int bytesum = 0;
  int byteread = 0;
  while ((byteread = inputStream.read(buffer)) != -1) {
   bytesum += byteread;
   outputStream.write(buffer, 0, byteread);
   outputStream.flush();
  }
  outputStream.close();
  inputStream.close();

  return path + multifile.getOriginalFilename();
 } 

 

ok,怎么样,spring处理附件上传很简单吧。

 

这里讨论这样一种情况,如果我实现不知道我要上传多少个附件,也不到对应的参数名称,比如使用FancyUpload这样的多附件上传组件,这又该如何处理呢?

 

其实很简单,只需要在处理器的方法中加入DefaultMultipartHttpServletRequest multipartRequest参数即可,还拿上面那个页面举例,controller的处理方法如下:

 

 

@RequestMapping(value = "/demo/uploadMulti.do")
 public String handleImport(Model model,
   DefaultMultipartHttpServletRequest multipartRequest) throws IOException {

  List<FileModel> list = new ArrayList<FileModel>();
  if (multipartRequest != null) {
   Iterator iterator = multipartRequest.getFileNames();

   while (iterator.hasNext()) {
    MultipartFile multifile =
    multipartRequest.getFile((String) iterator.next());
  
    if (StringUtils.hasText(multifile.getOriginalFilename())) {
     System.out.println(multifile.getOriginalFilename());
     FileModel fileModel = new FileModel();
     fileModel.setName(multifile.getOriginalFilename());
     fileModel.setSize(multifile.getSize());
     String path = service.saveFileToServer(multifile, ASVE_PATH);
     fileModel.setPath(path);
     list.add(fileModel);
    }

   }
  }

  model.addAttribute("list", list);
  return "demo/list";

 } 

 

 

与之前的方法相比,我们不再使用MultipartFile 参数,而改为使用DefaultMultipartHttpServletRequest 参数,其实这样做更为方便,可以批量处理。

 

 

另外,我们在配置

 

 

 

CommonsMultipartResolver时可以控制每次上传文件的大小,如下:

 

<bean id="multipartResolver"

class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

<!-- one of the properties available; the maximum file size in bytes -->

<property name="maxUploadSize" value="100000"/>

</bean>

 

PS:如果不想在配置文件中增加配置,又想使用spring对多附件上传的支持,该如何做呢,可以参考下面的例子:

 

 

@RequestMapping(value = "/test/upload2.do", method = POST)

public String handleImport2(Model model, HttpServletRequest request) {

CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver(

request.getSession().getServletContext());

// 设置编码

commonsMultipartResolver.setDefaultEncoding("utf-8");

if (commonsMultipartResolver.isMultipart(request)) {

// 转换成多部分request

MultipartHttpServletRequest multipartRequest = commonsMultipartResolver.resolveMultipart(request);

Iterator iterator = multipartRequest.getFileNames();

while (iterator.hasNext()) {

MultipartFile multifile = multipartRequest.getFile((String) iterator.next());

System.out.println(multifile.getOriginalFilename());

}

commonsMultipartResolver.cleanupMultipart(multipartRequest);

}

return null;

}

 

说明:这种方式不能在spring配置文件中声明multipartResolver,否则会得不到上传文件内容

 

 

ok,关于spring基于注解的附件上传就介绍到这里,相关代码可以参考附件。

 

 

 

 

 

  • 大小: 26 KB
3
0
分享到:
评论

相关推荐

    Struts2.X+Hibernate3.X+Spring2.5 整合

    标题"Struts2.X+Hibernate3.X+Spring2.5 整合"指的是将这三个框架的特定版本(Struts2.X,Hibernate3.X,Spring2.5)集成到同一个项目中,实现高效的企业级应用开发。这种整合能够充分利用各个框架的优势,使开发者...

    Spring-Reference_zh_CN(Spring中文参考手册)

    2.5.1. Spring MVC的表单标签库 2.5.2. Spring MVC合理的默认值 2.5.3. Portlet 框架 2.6. 其他特性 2.6.1. 动态语言支持 2.6.2. JMX 2.6 .3. 任务规划 2.6.4. 对Java 5(Tiger)的支持 2.7. 移植到Spring 2.0 ...

    Spring中文帮助文档

    13.8. Spring对分段文件上传(multipart file upload)的支持 13.8.1. 介绍 13.8.2. 使用MultipartResolver 13.8.3. 在表单中处理分段文件上传 13.9. 使用Spring的表单标签库 13.9.1. 配置 13.9.2. form标签 ...

    Spring API

    2. Spring 2.0和 2.5的新特性 2.1. 简介 2.2. 控制反转(IoC)容器 2.2.1. 新的bean作用域 2.2.2. 更简单的XML配置 2.2.3. 可扩展的XML编写 2.2.4. Annotation(注解)驱动配置 2.2.5. 在classpath中自动搜索组件...

    spring chm文档

    13.8. Spring对分段文件上传(multipart file upload)的支持 13.8.1. 介绍 13.8.2. 使用MultipartResolver 13.8.3. 在表单中处理分段文件上传 13.9. 使用Spring的表单标签库 13.9.1. 配置标签库 13.9.2. form...

    Spring 2.0 开发参考手册

    2.5.1. Spring MVC的表单标签库 2.5.2. Spring MVC合理的默认值 2.5.3. Portlet 框架 2.6. 其他特性 2.6.1. 动态语言支持 2.6.2. JMX 2.6.3. 任务规划 2.6.4. 对Java 5(Tiger)的支持 2.7. 移植到Spring ...

    JBoss Seam 工作原理、seam和hibernate的范例、RESTFul的seam、seam-gen起步、seam组件、配置组件、jsf,jboss、标签、PDF、注解等等

    Seam - 语境相关的组件[满江红20071230]............................................................................................................................ 1 Java EE 框架...........................

    JAVA上百实例源码以及开源项目源代码

    凯撒加密解密程序 1个目标文件 1、程序结构化,用函数分别实现 2、对文件的加密,解密输出到文件 利用随机函数抽取幸运数字 简单 EJB的真实世界模型(源代码) 15个目标文件 摘要:Java源码,初学实例,基于EJB的真实...

Global site tag (gtag.js) - Google Analytics