SpringMVC文件上传下载和拦截器

一、文件上传文件上传是项目开发中最常用的功能。为了能上传文件,必须将表单的method设置为post,将enctype设置为multipart/form-data。只有在这种情况下,浏览器才会把用户选择的文件二进制数据发送给服务器
 
     1、导入相应的jar包(上传组件): 
            commons-fileupload.jar
              common-io.jar
 
     2、上传的页面文件:
            <form action="upload" enctype="multipart/form-data" method="post">
          <label>请选择文件:</label>
              <input type="file" name="file">
              <br><br>
              <input type="submit" value="上传">
        </form>
    3、上传控制器:
       @Controller
       public class FileUploadController {
        @PostMapping("/upload")
        public String upload(@RequestParam("file") MultipartFile file) throws Exception{
          //如果文件不为空
            if(!file.isEmpty()) {
                 String path = "E:\upload";//上传路径
                 String filename = file.getOriginalFilename();//获取上传文件的原名
                 File filepath = new File(path,filename);
                 //判断路径是否存在,如果不存在就创建一个
                 if(!filepath.getParentFile().exists()) {
                      filepath.getParentFile().mkdirs();
                 }         
                 //将上传文件保存到一个目标文件中
                 file.transferTo(new File(path+File.separator+filename));
                 System.out.println("上传路径为:"+(path+File.separator+filename));
                 return "success";
                }else {
                 return "error";
              }
           }
        }
    4、配置SpringMVC
     <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
           <property name="maxUploadSize">
               <value>10345789</value>
           </property>
           <property name="defaultEncoding">
              <value>utf-8</value>
           </property>
       </bean>
    5、MultipartFile对象:SpringMVC回将上传文件绑定到MultipartFile对象。MultipartFile对象提供了获取上传文件内容、文件名等方法。通过transferTo()方法可以将文件上传。MultipartFile对象中的常用方法如下:
     (1)byte[] getBytes():获取文件数据
      (2)String getContentType():获取文件MIME类型,如image/jpeg等
      (3)InputStream getInputStream():获取文件流
      (4)String getName():获取表单中文件组件的名称
      (5)String getOriginalFilename():获取上传文件的原名
      (6)long getSize():获取文件的字节大小,单位为byte
      (7)boolean isEmpty():是否有上传文件
      (8)void transferTo(File dest):将上传文件保存到一个目标文件中
   
    6、实例:使用对象接收上传文件
      (1)上传页面:
          <form action="objectUploade" enctype="multipart/form-data" method="post"
               <label>用户名:</label>
               <input type="text" name="username">
               <br><br>
               <label>请选择头像:</label>
               <input type="file" name="image">
               <br><br>
               <input type="submit" value="上传">
             </form>
        (2)接收上传文件的类:
          public class User implements Serializable {
                private static final long serialVersionUID = 1L;
                private String username;
                private MultipartFile image;
              }
        (3)上传控制器:
             @PostMapping("/objectUploade")
             public String register(HttpServletRequest request,
                                    @ModelAttribute User user,
                                    Model model) throws Exception {
          
                 System.out.println(user.getUsername());
               if(!user.getImage().isEmpty()) {
                   String path = request.getServletContext().getRealPath("/images");
                   String filename = user.getImage().getOriginalFilename();
                   File filepath = new File(path,filename);
              
                  if(!filepath.getParentFile().exists()) {
                        filepath.getParentFile().mkdirs();
                    }
                   user.getImage().transferTo(new File(path+File.separator+filename));
                   model.addAttribute("filename",user.getImage().getOriginalFilename());
                   System.out.println("上传文件路径:"+(path+File.separator+filename));
              
                     return "userInfo";
                   }else {
                      return "error";
                  }
               }
          (4)下载页面(userInfo.jsp)
            <a href="javascript:window.location.href='download?filename='+encodeURIComponent('${requestScope.filename }')">
                    ${requestScope.filename }
                </a>
   注:因为传递的文件名有可能是中文字符,所以超链接中使用了encodeURIComponent函数进行编码
二、文件下载:SpringMVC提供了ResponseEntity类型,使用它可以很方便的定义返回的BodyBuilder、HttpHeaders和HttpStatus
                        
               BodyBuilder对象用来构建返回的Body;
               HttpHeaders代码Http协议中的头信息
               HttpStatus代表Http协议中的状态
  接上例,定义下载的控制器:
         @GetMapping("/download")
            public ResponseEntity<byte[]> download(HttpServletRequest request,
                                        @RequestParam("filename") String filename,
                                        @RequestHeader("User-Agent") String userAgent) throws Exception{
          
            String path =request.getServletContext().getRealPath("/images");
            File file = new File(path+File.separator+filename);
            BodyBuilder builder = ResponseEntity.ok();//ok表示http协议中的状态200
            builder.contentLength(file.length());//内容长度
           
            //application_octet_stream二进制流数据(最常见的文件下载),MediaType表示互联网媒体类型,即MIME类型
            builder.contentType(MediaType.APPLICATION_OCTET_STREAM);
           
            //使用URLEncoder.encode对文件名进行解码
            filename = URLEncoder.encode(filename,"utf-8");
           
           //设置实际的响应文件名,告诉浏览器文件要以附件的形式打开
           //不同的浏览器,处理方式不同,要根据浏览器版本进行区别判断
            if(userAgent.indexOf("MSIE")>0) {
                //如果是IE,只需要用utf-8字符集进行URL编码即可
                builder.header("Content-Disposition","attachment;filename="+filename);
            }else {
                //如果是fireFox、Chrome等浏览器,则需要说明编码的字符集
                //注意在filename后面有个*号,在utf-8后面有两个单引号
                builder.header("Content-Disposition", "attachment;filename*=utf-8''"+filename);
            }
                return builder.body(FileUtils.readFileToByteArray(file));
          }
三、拦截器:Inteceptor拦截器是SpringMVC中非常重要的功能,它的主要作用是拦截用户的请求并进行相应的处理。比如通过拦截器来进行用户权限验证、或判断用户是否已经登录等。
        1、SpringMVC拦截器是可插拔的。如果需要只需在配置文件中配置即可,如果不需要在配置文件取消配置即可
    2、SpringMVC拦截器拦截请求是通过实现HandlerInterceptor接口来完成的,在该接口中定义了三个方法来对用户的请求进行拦截
         (1)boolean  preHandle(request,response,object):该方法在请求处理之前进行调用
         (2)void postHandle(request,response,handler,modelAndView)在Controller方法调用之后执行
         (3)void afterHandle(request,response,handler,modelAndView):进行资源清理
    3、示例:实现登录验证
        (1)请求控制器:模拟在数据库中查找用户,判断用户登录
           @PostMapping(value="/login")
              public ModelAndView login(String loginname,String password,
                                ModelAndView mv,HttpSession session) {
              if(loginname!=null&&loginname.equals("jaskon")&&password!=null&&password.equals("12345")) {
                  User user = new User();
                  user.setLoginname(loginname);
                  user.setPassword(password);
                  user.setUsername("管理员");
                  session.setAttribute("user",user);
                  mv.setViewName("redirect:main");
              }else {
                  mv.addObject("message","登录名或密码错误,请重新输入!");
                  mv.setViewName("loginForm");
              }
                 return mv;
             }
       (2)主页面控制器(main)
           @Controller
               public class BookController {
                @RequestMapping(value="/main")
                  public String Main(Model model) {
                       model.addAttribute("Info","欢迎管理员");
                       return "main";
                  }
                }
         (3)自定义拦截器:MyInterceptor
             public class MyInterceptor implements HandlerInterceptor {
                     private static final String[] IGNORE_URI = {"/loginForm","/login"};
                   @Override
                   public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                     throws Exception {
                        System.out.println("MyInterceptor preHandle...");
          
                        boolean flag = false;
                        String servletPath = request.getServletPath();
                        for(String s : IGNORE_URI) {
                             if(servletPath.contains(s)) {
                                 flag = true;
                                  break;
                              }
                          }
                         if(!flag) {
                             User user= (User)request.getSession().getAttribute("user");
                              if(user == null) {
                                 System.out.println("MyInterceptor拦截请求");
                                 request.setAttribute("message","请先登录");
                                 request.getRequestDispatcher("/WEB-INF/views/loginForm.jsp").forward(request, response);
                               }else {
                                   System.out.println("MyInterceptor放行请求");
                                   flag = true;
                                }
                            }
                      return flag;
                 }
                    @Override
                    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                        ModelAndView modelAndView) throws Exception {
          
                          System.out.println("MyInterceptor postHandle...");
                      }
                    @Override
                   public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
                          throws Exception {
                      System.out.println("MyInterceptor afterCompletion...");
                    }
               }
        (4)配置拦截器:
             <mvc:interceptors>
                       <mvc:interceptor>
                          <mvc:mapping path="/*"/>
                          <bean class="com.cn.filter.MyInterceptor"></bean>
                       </mvc:interceptor>
                 </mvc:interceptors>
         (5)页面(main.jsp) 
             <h2>${sessionScope.user.username }</h2>
                  <h2>${Info }</h2>
原文地址:https://www.cnblogs.com/lone5wolf/p/10943850.html