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>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM