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工程,工程结构如下图所示:

 

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

 

关于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基于注解的附件上传就介绍到这里,相关代码可以参考附件。

 

 

 

 

 

你可能感兴趣的:(spring,bean,mvc,Web,servlet)