文件上传

◾使用apache的commons-io和commons-fileupload实现文件上传
◾使用servlet3.0实现文件上传

文件上传方式一

文件上传的jsp中的表单

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<form enctype="multipart/form-data" action="/uploadfile.do" method="post">
 图片:<input type="file" name="photo">
   <input type="submit" value="上传">
</form>
</body>
</html>

编写处理文件上传的controller,在处理文件上传的方法中需要添加MultipartFile类型的参数,MultipartFile本身是一个接口,里面提供了一些文件上传的操作的方法:

◾getOriginalFilename()
  获得文件名
◾isEmpty()
  判断是否上传了文件,如果没有选择文件上传的话,此时结果为true
◾getContentType()
  获得上传文件的文件类型
◾transferTo(File file)
  将文件上传至指定目录中
◾getName()
  获取表单中input的name值
◾getBytes()
  获取上传文件的byte数组
◾getInputStream()
  获取上传文件的InputStream对象

方法中的另外一个参数HttpSession的主要作用就是获取服务器中用来存放上传文件的路径。

package com.davis.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpSession;
import java.io.File;

@Controller
public class fileupload {
  @RequestMapping("/uploadfile.do")
  public ModelAndView uploadFile(MultipartFile photo, HttpSession session)throws Exception{
      ModelAndView mv = new ModelAndView();
      //判断是否上传了文件
      if(!photo.isEmpty()){
          //获取服务器接收的路径
          String path=session.getServletContext().getRealPath("/images");
          //获取文件上传的名称
          String filename= photo.getOriginalFilename();
          //规定上传的文件类型
          if("image/jpeg".equals(photo.getContentType())){
          File file=new File(path,filename);
          //完成文件上传
              photo.transferTo(file);
          }else{
              mv.addObject("mse","上传图片格式错误,请上传jpg格式图片!!");
              mv.setViewName("uploadFailed");
              return mv;
          }
      }else{
          mv.addObject("mse","请选择jpg图片上传!");
          mv.setViewName("uploadFailed");
          return mv;
      }
      //跳转到成功页面
      mv.addObject("pic",photo.getOriginalFilename());
      mv.setViewName("uploadsuccessful");
      return mv;
  }
}

导入相关jar包:

<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>

在springmvc.xml配置文件中添加multipartResolver,这里的id必须要写成multipartResolver,会有DispatcherServlet来调用,我们可以在这里设置上传文件大小、字符编码等内容:

 <!--注册一个multipartResolver,由DispatcherServlet来调用 -->
  <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
      <!--设置字符编码防止文件名乱码-->
      <property name="defaultEncoding" value="utf-8"/>
      <!--设置单个上传文件的大小,单位是字节b-->
      <property name="maxUploadSizePerFile" value="1048576"/>

  </bean>
<!--注册multipartResolver,由DispatcherServlet来负责调用-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
  <!--设置字符编码防止文件名乱码-->
  <property name="defaultEncoding" value="utf-8"/>
  <!--设置上传文件的总大小,单位是字节b-->
  <property name="maxUploadSize" value="1048576"/>
  <!--设置单个上传文件的大小,单位是字节b-->
  <property name="maxUploadSizePerFile" value="1048576"/>
  <!--设置内存缓冲区的大小,当超过该值的时候会写入到临时目录-->
  <property name="maxInMemorySize" value="1048576"/>
  <!--设置临时目录-->
  <property name="uploadTempDir" value="tempupload"/>
  <!--默认是false,如果设置为true的话,不会将文件路径去除,在IE浏览器下上传时会将路径名也作为文件名上传:D:\image\1.jpg-->
  <property name="preserveFilename" value="false"/>
  <!--是否使用懒加载,默认是false-->
  <property name="resolveLazily" value="true"/>
</bean>

设置临时上传文件目录的作用:

◾提高安全性
  客户端上传的文件直接传到临时目录,这样子对于客户端来说隐藏了真实的文件存放目录
◾便于管理
  当用户取消上传或上传失败的话,直接操作临时目录即可,无需再去修改真实目录中的文件。

将上面内容设置完毕之后,就可以实现文件上传了。

文件上传方式二

在web.xml中的中央控制器的servlet配置里面添加下面内容,location的标签需要写在multipart-config中的第一行:

<!--使用servlet3.0实现文件上传-->
  <multipart-config>
      <!--临时文件路径-->
      <location>/temp</location>
      <!--单个上传文件的最大值,单位是byte-->
      <max-file-size>100</max-file-size>
      <!--总上传文件的最大值-->
      <max-request-size>52428800</max-request-size>
      <!--内存缓冲区的大小,当超过该值时,会写入到临时文件中,单位是byte-->
      <file-size-threshold>1024</file-size-threshold>
  </multipart-config>

然后需要在springmvc.xml文件中配置multipartResolver

<bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver"/>

配置完成后,spring mvc就会使用servlet3.0来实现文件上传了。

上传文件超出设定大小的异常处理

当上传文件超出指定大小时,会抛出 MaxUploadSizeExceededException 异常。我们可以通过之前讲过的spring mvc异常处理方式来进行处理,给用户一个友好的提示信息,此部分可以参考之前讲过的spring mvc异常处理内容。

多文件上传

修改jsp,多个input的name相同:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<form enctype="multipart/form-data" action="/uploadfile.do" method="post">
  图片1:<input type="file" name="photos"><br>
  图片2:<input type="file" name="photos"><br>
  图片3:<input type="file" name="photos"><br>
   <input type="submit" value="上传">
</form>
</body>
</html>

在controller中添加方法,方法参数中需要添加MultipartFile[],并且要在其前面加上@RequestParam注解:

package com.davis.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpSession;
import java.io.File;

@Controller
public class fileupload {
  @RequestMapping("/uploadfile.do")
  public ModelAndView uploadFile(@RequestParam MultipartFile[] photos, HttpSession session)throws Exception {

      ModelAndView mv = new ModelAndView();
      //获取服务器上传的文件路径
      String path = session.getServletContext().getRealPath("/images");
      for (MultipartFile photo : photos) {
          if (!photo.isEmpty()) {

              //获取文件名称
              String filename = photo.getOriginalFilename();
              System.out.println(filename);
              //限制文件上传的类型
              if ("image/jpeg".equals(photo.getContentType())) {
                  File file = new File(path, filename);
                  //完成文件上传
                  photo.transferTo(file);
              } else {
                  mv.addObject("mse", "请选择jpg格式的文件上传");
                  mv.setViewName("/uploadFailed");

                  return mv;
              }

          }
      }
      mv.setViewName("/uploadsuccessful");
      return mv;
  }
}