1. 程式人生 > >springmvc核心技術

springmvc核心技術

目錄

  • 異常處理
  • 型別轉換器
  • 資料驗證
  • 檔案上傳與下載
  • 攔截器

 異常處理

Spring MVC中, 系統的DAO, Service, Controller層出現異常, 均通過throw Exception向上丟擲,

最後由中央處理器DispatchServlet交由全域性異常處理器進行異常處理, 如下圖所示

常用的Spring MVC異常處理方式主要有三種:

  • 使用系統定義好的異常處理器SimpleMappingExceptionResolver
  • 使用自定義異常處理器
  • 使用異常註解

SimpleMappingExceptionResolver

只需要在配置檔案中註冊該異常處理器Bean即可, 無需顯式呼叫, 當異常發生時會自動執行該類.

1     <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
2         <property name="defaultErrorView" value="/errors/error.jsp"/>
3     </bean>

(1) 宣告一個自定義的異常類

複製程式碼
 1 public class NameException extends Exception {
 2 
 3     public NameException() {
 4         super();
 5     }
 6 
 7     public NameException(String message) {
 8         super(message);
 9     }
10     
11 }
複製程式碼

(2) 註冊異常處理器

複製程式碼
1     <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
2         <property name="defaultErrorView" value="/errors/error.jsp"/>
3         <property name="exceptionAttribute" value="ex"/>
4         <property name="exceptionMappings">
5             <props>
6                 <prop key="com.test.exceptions.NameException">/errors/nameError.jsp</prop>
7             </props>
8         </property>
9     </bean>
複製程式碼

exceptionMapping: Properties型別屬性, 用於指定具體的不同型別異常對應的響應頁面.

defaultErrorView: 預設的異常響應頁面, 若發生的異常不是自定義的異常, 則使用預設響應頁面.

exceptionAttribute: 捕獲到的異常物件, 一般異常響應頁面中使用.

自定義異常處理器

SimpleMappingExceptionResolver可以在發生異常的時候進行頁面跳轉, 但是如果想要在捕獲到特定異常後, 

執行一些操作, 則需要自定義異常. 自定義異常處理器需要實現HandlerExceptionResolver介面, 並且該類

需要在配置檔案中進行註冊.

(1) 定義異常處理器

當一個類實現了HandlerExceptionResolver介面後, 只要有異常發生, 都會執行resolveException方法.

複製程式碼
 1 public class MyHandlerExceptionResolver implements HandlerExceptionResolver {
 2 
 3     public ModelAndView resolveException(HttpServletRequest request,
 4             HttpServletResponse response, Object handler, Exception ex) {
 5         
 6         ModelAndView mv = new ModelAndView();
 7         mv.addObject("ex", ex);
 8         mv.setViewName("/errors/error.jsp");
 9         
10         if(ex instanceof NameException) {
11             // 執行一些操作
12             mv.setViewName("/errors/nameError.jsp");
13         }
14         
15         return mv;
16     }
17 
18 }
複製程式碼

(2) 註冊異常處理器

1     <!-- 註冊異常處理器 -->
2     <bean class="com.test.resolvers.MyHandlerExceptionResolver"/>

異常處理註解

使用註解@ExceptionHandler可以將一個方法指定為異常處理方法, 該註解有一個可選屬性value,

可用於指定該註解方法所需要處理的異常類. 

定義一個頂層Controller, 處理所有異常, 其他Controller繼承該類即可實現異常集中管理.

複製程式碼
 1 @Controller    
 2 public class BaseController {
 3 
 4     // 處理NameException異常
 5     @ExceptionHandler(NameException.class)
 6     public ModelAndView handlerNameException(Exception ex) {
 7         ModelAndView mv = new ModelAndView();
 8         mv.addObject("ex", ex);
 9         // 執行一些操作
10         mv.setViewName("/errors/nameError.jsp");
11         return mv;
12     }
13 
14 }
複製程式碼

型別轉換器

可以將使用者web端提交的資料, 在後臺轉為需要的資料型別.

自定義型別轉換器

若要定義型別轉換器, 則需要實現Converter介面, 該Convert介面有兩個泛型:

第一個為待轉換型別, 第二個為目標型別, 該介面方法convert用於實現轉換.

複製程式碼
 1 public class MyDateConverter implements Converter<String, Date> {
 2 
 3     public Date convert(String source) {
 4         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
 5         try {
 6             return sdf.parse(source);
 7         } catch (ParseException e) {   
 8             e.printStackTrace();
 9         }
10         return null;
11     }
12 
13 }
複製程式碼

型別轉換器定義完畢後, 需要在配置檔案中進行註冊, 然後註冊一個轉換服務Bean, 將轉換器注入給該Bean, 

最後由處理器介面卡來使用該轉換伺服器Bean. 該Bean由ConversionServiceFactory工廠建立, 工廠有Set集合屬性, 

可以提供多種轉換功能的Bean來處理多種資料型別轉換.

複製程式碼
 1     <!-- 註冊型別轉換器 -->
 2     <bean id="myDateConverter" class="com.test.converters.MyDateConverter"/>
 3     
 4     <!-- 註冊轉換服務物件 -->
 5     <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
 6         <property name="converters" ref="myDateConverter"/>
 7     </bean>
 8     
 9     <!-- 註冊mvc註解驅動 -->
10     <mvc:annotation-driven conversion-service="conversionService"/>
複製程式碼

資料驗證

主要是校驗客戶端發來的資料是否合法, 例如不能為空, 或者長度不符合等等. Spring MVC沒有校驗功能,

但是支援JSR303-Bean Validation, 可以用實現該規範的Hibernate Validator校驗框架.

(1) 配置驗證器

1     <!-- 生成驗證器 -->
2     <bean id="myValidator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
3         <property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
4     </bean>

(2) 在Bean上新增驗證註解

複製程式碼
 1 public class Student {
 2     
 3     @NotNull(message="姓名不能為空")
 4     @Size(min=3, max=6, message="姓名長度應在{min}-{max}個字元")
 5     private String name;
 6     
 7     @Min(value=0, message="成績不能小於{value}")
 8     @Max(value=100, message="成績不能大於{value}")
 9     private double score;
10     
11     
12     @NotNull(message="電話不能為空")
13     @Pattern(regexp="^1[34578]\\d{9}$", message="手機號格式不正確")
14     private String mobile;
15 
16         ......
17 }
複製程式碼

(3) 修改Controller

在需要校驗的引數前面加上@Validated註解, 同時追加一個BindingResult引數, 用於獲取驗證異常資訊.

複製程式碼
 1 @Controller    
 2 @RequestMapping("/test")    
 3 public class MyController {
 4 
 5     @RequestMapping("/register.do")
 6     public ModelAndView doRegister(@Validated Student student, BindingResult br) {
 7         
 8         ModelAndView mv = new ModelAndView();
 9         mv.addObject("student", student);
10         mv.setViewName("/WEB-INF/jsp/welcome.jsp");
11         
12         int errorCount = br.getErrorCount();
13         if(errorCount > 0) {
14             FieldError nameError = br.getFieldError("name");
15             
16             if (nameError != null) {
17                 String nameErrorMSG = nameError.getDefaultMessage();
18                 mv.addObject("nameErrorMSG", nameErrorMSG);
19             }
20             mv.setViewName("/index.jsp");
21         }
22         
23         return mv;
24     }
25 }
複製程式碼

檔案上傳與下載

上傳

Spring MVC中檔案上傳需要新增Apache Commons FileUpload相關的jar包,

基於該jar, Spring中提供了MultipartResolver實現類: CommonsMultipartResolver.

註冊該Bean到配置檔案中

複製程式碼
   <bean id="multipartResolver"  
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">  
        <!-- 上傳檔案大小上限,單位為位元組(10MB) -->
        <property name="maxUploadSize">  
            <value>10485760</value>  
        </property>  
        <!-- 請求的編碼格式,必須和jSP的pageEncoding屬性一致,以便正確讀取表單的內容,預設為ISO-8859-1 -->
        <property name="defaultEncoding">
            <value>UTF-8</value>
        </property>
    </bean>
複製程式碼

Spring MVC會將上傳的檔案繫結到MultipartFile物件, 該物件提供獲取內容, 檔名等方法.

通過transferTo方法可以將檔案儲存到磁碟.

複製程式碼
 1      //上傳檔案會自動繫結到MultipartFile中
 2      @RequestMapping(value="/upload",method=RequestMethod.POST)
 3      public String upload(HttpServletRequest request,
 4             @RequestParam("description") String description,
 5             @RequestParam("file") MultipartFile file) throws Exception {
 6 
 7         System.out.println(description);
 8         //如果檔案不為空,寫入上傳路徑
 9         if(!file.isEmpty()) {
10             //上傳檔案路徑
11             String path = request.getServletContext().getRealPath("/images/");
12             //上傳檔名
13             String filename = file.getOriginalFilename();
14             File filepath = new File(path,filename);
15             //判斷路徑是否存在,如果不存在就建立一個
16             if (!filepath.getParentFile().exists()) { 
17                 filepath.getParentFile().mkdirs();
18             }
19             //將上傳檔案儲存到一個目標檔案當中
20             file.transferTo(new File(path + File.separator + filename));
21             return "success";
22         } else {
23             return "error";
24         }
25 
26      }
複製程式碼

下載

下載比較簡單, Spring MVC中提供了ResponseEntity型別, 可以很方便的返回HTTPHeaders, HttpStatus.

複製程式碼
     @RequestMapping(value="/download")
     public ResponseEntity<byte[]> download(HttpServletRequest request,
             @RequestParam("filename") String filename,
             Model model)throws Exception {
        //下載檔案路徑
        String path = request.getServletContext().getRealPath("/images/");
        File file = new File(path + File.separator + filename);
        HttpHeaders headers = new HttpHeaders();  
        //下載顯示的檔名,解決中文名稱亂碼問題  
        String downloadFielName = new String(filename.getBytes("UTF-8"),"iso-8859-1");
        //通知瀏覽器以attachment(下載方式)開啟圖片
        headers.setContentDispositionFormData("attachment", downloadFielName); 
        //application/octet-stream : 二進位制流資料(最常見的檔案下載)。
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),    
                headers, HttpStatus.CREATED);  
     }
複製程式碼

攔截器

攔截器註冊與使用

Spring MVC中攔截器需要實現HandlerInterceptor介面, 該介面包含三個方法

preHandle(req, res, handler)

在處理器方法之前執行, 返回boolean, 若為true, 則緊接著執行處理器方法, 且會將

afterCompletion()方法放入一個專門的方法棧中等待執行.

postHandler(req, res, handler, ModelAndView)

在處理器方法之後執行, 處理器方法若未執行, 則該方法不執行.

該方法可以修改處理器方法返回的結果, 並可以跳轉到其他頁面.

afterCompletion(req, res, handler, exception)

當preHandle返回ture後, 會將該方法放入等待區, 等所有請求響應結束, 執行該方法.

即中央處理器渲染了響應頁面之後執行, 此時對ModelAndView修改也不會影響到頁面結果.

複製程式碼
 1 public class OneInterceptor implements HandlerInterceptor {
 2 
 3     public boolean preHandle(HttpServletRequest request,
 4             HttpServletResponse response, Object handler) throws Exception {
 5         System.out.println("執行OneIntercepor ---- preHandle() ------");
 6         return false;
 7     }
 8 
 9     public void postHandle(HttpServletRequest request,
10             HttpServletResponse response, Object handler,
11             ModelAndView modelAndView) throws Exception {
12         System.out.println("執行OneIntercepor ---- postHandle() ------");
13     }
14 
15     public void afterCompletion(HttpServletRequest request,
16             HttpServletResponse response, Object handler, Exception ex)
17             throws Exception {
18         System.out.println("執行OneIntercepor ---- afterCompletion() ------");
19     }
20 
21 }
複製程式碼

在配置檔案中註冊

複製程式碼
1     <!-- 註冊攔截器 -->
2     <mvc:interceptors>
3         <mvc:interceptor>
4             <mvc:mapping path="/**"/>
5             <bean class="com.test.interceptors.OneInterceptor"/>
6         </mvc:interceptor>
7     </mvc:interceptors>
複製程式碼

 

<mvc:mapping/>用於指定當前攔截器攔截的請求路徑, /**表示攔截所有請求.

多個攔截器

當有多個攔截器時, 形成攔截器鏈, 攔截器鏈執行順序與註冊順序一致, 需要注意的是,

當一個攔截器preHandle()返回false時, 上部的攔截器鏈將被斷開, 後續的處理器以及對於的postHandle()

都無法執行, 只有已經執行通過的攔截器的afterCompletion()方法會執行.

實際運用

  • 許可權校驗: 判斷當前請求是否登陸, 若未登入或者無許可權, 返回對應的介面.
  • 效能監控: 監控系統指定方法執行的時間, 尋找系統性能調優點.
  • 日誌列印: 記錄請求日誌, 用於系統監控, 資訊統計與分析等等.
  • ......
  • 異常處理
  • 型別轉換器
  • 資料驗證
  • 檔案上傳與下載
  • 攔截器

 異常處理

Spring MVC中, 系統的DAO, Service, Controller層出現異常, 均通過throw Exception向上丟擲,

最後由中央處理器DispatchServlet交由全域性異常處理器進行異常處理, 如下圖所示

常用的Spring MVC異常處理方式主要有三種:

  • 使用系統定義好的異常處理器SimpleMappingExceptionResolver
  • 使用自定義異常處理器
  • 使用異常註解

SimpleMappingExceptionResolver

只需要在配置檔案中註冊該異常處理器Bean即可, 無需顯式呼叫, 當異常發生時會自動執行該類.

1     <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
2         <property name="defaultErrorView" value="/errors/error.jsp"/>
3     </bean>

(1) 宣告一個自定義的異常類

複製程式碼
 1 public class NameException extends Exception {
 2 
 3     public NameException() {
 4         super();
 5     }
 6 
 7     public NameException(String message) {
 8         super(message);
 9     }
10     
11 }
複製程式碼

(2) 註冊異常處理器

複製程式碼
1     <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
2         <property name="defaultErrorView" value="/errors/error.jsp"/>
3         <property name="exceptionAttribute" value="ex"/>
4         <property name="exceptionMappings">
5             <props>
6                 <prop key="com.test.exceptions.NameException">/errors/nameError.jsp</prop>
7             </props>
8         </property>
9     </bean>
複製程式碼

exceptionMapping: Properties型別屬性, 用於指定具體的不同型別異常對應的響應頁面.

defaultErrorView: 預設的異常響應頁面, 若發生的異常不是自定義的異常, 則使用預設響應頁面.

exceptionAttribute: 捕獲到的異常物件, 一般異常響應頁面中使用.

自定義異常處理器

SimpleMappingExceptionResolver可以在發生異常的時候進行頁面跳轉, 但是如果想要在捕獲到特定異常後, 

執行一些操作, 則需要自定義異常. 自定義異常處理器需要實現HandlerExceptionResolver介面, 並且該類

需要在配置檔案中進行註冊.

(1) 定義異常處理器

當一個類實現了HandlerExceptionResolver介面後, 只要有異常發生, 都會執行resolveException方法.

複製程式碼
 1 public class MyHandlerExceptionResolver implements HandlerExceptionResolver {
 2 
 3     public ModelAndView resolveException(HttpServletRequest request,
 4             HttpServletResponse response, Object handler, Exception ex) {
 5         
 6         ModelAndView mv = new ModelAndView();
 7         mv.addObject("ex", ex);
 8         mv.setViewName("/errors/error.jsp");
 9         
10         if(ex instanceof NameException) {
11             // 執行一些操作
12             mv.setViewName("/errors/nameError.jsp");
13         }
14         
15         return mv;
16     }
17 
18 }
複製程式碼

(2) 註冊異常處理器

1     <!-- 註冊異常處理器 -->
2     <bean class="com.test.resolvers.MyHandlerExceptionResolver"/>

異常處理註解

使用註解@ExceptionHandler可以將一個方法指定為異常處理方法, 該註解有一個可選屬性value,

可用於指定該註解方法所需要處理的異常類. 

定義一個頂層Controller, 處理所有異常, 其他Controller繼承該類即可實現異常集中管理.

複製程式碼
 1 @Controller    
 2 public class BaseController {
 3 
 4     // 處理NameException異常
 5     @ExceptionHandler(NameException.class)
 6     public ModelAndView handlerNameException(Exception ex) {
 7         ModelAndView mv = new ModelAndView();
 8         mv.addObject("ex", ex);
 9         // 執行一些操作
10         mv.setViewName("/errors/nameError.jsp");
11         return mv;
12     }
13 
14 }
複製程式碼

型別轉換器

可以將使用者web端提交的資料, 在後臺轉為需要的資料型別.

自定義型別轉換器

若要定義型別轉換器, 則需要實現Converter介面, 該Convert介面有兩個泛型:

第一個為待轉換型別, 第二個為目標型別, 該介面方法convert用於實現轉換.

複製程式碼
 1 public class MyDateConverter implements Converter<String, Date> {
 2 
 3     public Date convert(String source) {
 4         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
 5         try {
 6             return sdf.parse(source);
 7         } catch (ParseException e) {   
 8             e.printStackTrace();
 9         }
10         return null;
11     }
12 
13 }
複製程式碼

型別轉換器定義完畢後, 需要在配置檔案中進行註冊, 然後註冊一個轉換服務Bean, 將轉換器注入給該Bean, 

最後由處理器介面卡來使用該轉換伺服器Bean. 該Bean由ConversionServiceFactory工廠建立, 工廠有Set集合屬性, 

可以提供多種轉換功能的Bean來處理多種資料型別轉換.

複製程式碼
 1     <!-- 註冊型別轉換器 -->
 2     <bean id="myDateConverter" class="com.test.converters.MyDateConverter"/>
 3     
 4     <!-- 註冊轉換服務物件 -->
 5     <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
 6         <property name="converters" ref="myDateConverter"/>
 7     </bean>
 8     
 9     <!-- 註冊mvc註解驅動 -->
10     <mvc:annotation-driven conversion-service="conversionService"/>
複製程式碼

資料驗證

主要是校驗客戶端發來的資料是否合法, 例如不能為空, 或者長度不符合等等. Spring MVC沒有校驗功能,

但是支援JSR303-Bean Validation, 可以用實現該規範的Hibernate Validator校驗框架.

(1) 配置驗證器

1     <!-- 生成驗證器 -->
2     <bean id="myValidator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
3         <property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
4     </bean>

(2) 在Bean上新增驗證註解

複製程式碼
 1 public class Student {
 2     
 3     @NotNull(message="姓名不能為空")
 4     @Size(min=3, max=6, message="姓名長度應在{min}-{max}個字元")
 5     private String name;
 6     
 7     @Min(value=0, message="成績不能小於{value}")
 8     @Max(value=100, message="成績不能大於{value}")
 9     private double score;
10     
11     
12     @NotNull(message="電話不能為空")
13     @Pattern(regexp="^1[34578]\\d{9}$", message="手機號格式不正確")
14     private String mobile;
15 
16         ......
17 }
複製程式碼

(3) 修改Controller

在需要校驗的引數前面加上@Validated註解, 同時追加一個BindingResult引數, 用於獲取驗證異常資訊.

複製程式碼
 1 @Controller    
 2 @RequestMapping("/test")    
 3 public class MyController {
 4 
 5     @RequestMapping("/register.do")
 6     public ModelAndView doRegister(@Validated Student student, BindingResult br) {
 7         
 8         ModelAndView mv = new ModelAndView();
 9         mv.addObject("student", student);
10         mv.setViewName("/WEB-INF/jsp/welcome.jsp");
11         
12         int errorCount = br.getErrorCount();
13         if(errorCount > 0) {
14             FieldError nameError = br.getFieldError("name");
15             
16             if (nameError != null) {
17                 String nameErrorMSG = nameError.getDefaultMessage();
18                 mv.addObject("nameErrorMSG", nameErrorMSG);
19             }
20             mv.setViewName("/index.jsp");
21         }
22         
23         return mv;
24     }
25 }
複製程式碼

檔案上傳與下載

上傳

Spring MVC中檔案上傳需要新增Apache Commons FileUpload相關的jar包,

基於該jar, Spring中提供了MultipartResolver實現類: CommonsMultipartResolver.

註冊該Bean到配置檔案中

複製程式碼
   <bean id="multipartResolver"  
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">  
        <!-- 上傳檔案大小上限,單位為位元組(10MB) -->
        <property name="maxUploadSize">  
            <value>10485760</value>  
        </property>  
        <!-- 請求的編碼格式,必須和jSP的pageEncoding屬性一致,以便正確讀取表單的內容,預設為ISO-8859-1 -->
        <property name="defaultEncoding">
            <value>UTF-8</value>
        </property>
    </bean>
複製程式碼

Spring MVC會將上傳的檔案繫結到MultipartFile物件, 該物件提供獲取內容, 檔名等方法.

通過transferTo方法可以將檔案儲存到磁碟.

複製程式碼
 1      //上傳檔案會自動繫結到MultipartFile中
 2      @RequestMapping(value="/upload",method=RequestMethod.POST)
 3      public String upload(HttpServletRequest request,
 4             @RequestParam("description") String description,
 5             @RequestParam("file") MultipartFile file) throws Exception {
 6 
 7         System.out.println(description);
 8         //如果檔案不為空,寫入上傳路徑
 9         if(!file.isEmpty()) {
10             //上傳檔案路徑
11             String path = request.getServletContext().getRealPath("/images/");
12             //上傳檔名
13             String filename = file.getOriginalFilename();
14             File filepath = new File(path,filename);
15             //判斷路徑是否存在,如果不存在就建立一個
16             if (!filepath.getParentFile().exists()) { 
17                 filepath.getParentFile().mkdirs();
18             }
19             //將上傳檔案儲存到一個目標檔案當中
20             file.transferTo(new File(path + File.separator + filename));
21             return "success";
22         } else {
23             return "error";
24         }
25 
26      }
複製程式碼

下載

下載比較簡單, Spring MVC中提供了ResponseEntity型別, 可以很方便的返回HTTPHeaders, HttpStatus.

複製程式碼
     @RequestMapping(value="/download")
     public ResponseEntity<byte[]> download(HttpServletRequest request,
             @RequestParam("filename") String filename,
             Model model)throws Exception {
        //下載檔案路徑
        String path = request.getServletContext().getRealPath("/images/");
        File file = new File(path + File.separator + filename);
        HttpHeaders headers = new HttpHeaders();  
        //下載顯示的檔名,解決中文名稱亂碼問題  
        String downloadFielName = new String(filename.getBytes("UTF-8"),"iso-8859-1");
        //通知瀏覽器以attachment(下載方式)開啟圖片
        headers.setContentDispositionFormData("attachment", downloadFielName); 
        //application/octet-stream : 二進位制流資料(最常見的檔案下載)。
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),    
                headers, HttpStatus.CREATED);  
     }
複製程式碼

攔截器

攔截器註冊與使用

Spring MVC中攔截器需要實現HandlerInterceptor介面, 該介面包含三個方法

preHandle(req, res, handler)

在處理器方法之前執行, 返回boolean, 若為true, 則緊接著執行處理器方法, 且會將

afterCompletion()方法放入一個專門的方法棧中等待執行.

postHandler(req, res, handler, ModelAndView)

在處理器方法之後執行, 處理器方法若未執行, 則該方法不執行.

該方法可以修改處理器方法返回的結果, 並可以跳轉到其他頁面.

afterCompletion(req, res, handler, exception)

當preHandle返回ture後, 會將該方法放入等待區, 等所有請求響應結束, 執行該方法.

即中央處理器渲染了響應頁面之後執行, 此時對ModelAndView修改也不會影響到頁面結果.

複製程式碼
 1 public class OneInterceptor implements HandlerInterceptor {
 2 
 3     public boolean preHandle(HttpServletRequest request,
 4             HttpServletResponse response, Object handler) throws Exception {
 5         System.out.println("執行OneIntercepor ---- preHandle() ------");
 6         return false;
 7     }
 8 
 9     public void postHandle(HttpServletRequest request,
10             HttpServletResponse response, Object handler,
11             ModelAndView modelAndView) throws Exception {
12         System.out.println("執行OneIntercepor ---- postHandle() ------");
13     }
14 
15     public void afterCompletion(HttpServletRequest request,
16             HttpServletResponse response, Object handler, Exception ex)
17             throws Exception {
18         System.out.println("執行OneIntercepor ---- afterCompletion() ------");
19     }
20 
21 }
複製程式碼

在配置檔案中註冊

複製程式碼
1     <!-- 註冊攔截器 -->
2     <mvc:interceptors>
3         <mvc:interceptor>
4             <mvc:mapping path="/**"/>
5             <bean class="com.test.interceptors.OneInterceptor"/>
6         </mvc:interceptor>
7     </mvc:interceptors>
複製程式碼

 

<mvc:mapping/>用於指定當前攔截器攔截的請求路徑, /**表示攔截所有請求.

多個攔截器

當有多個攔截器時, 形成攔截器鏈, 攔截器鏈執行順序與註冊順序一致, 需要注意的是,

當一個攔截器preHandle()返回false時, 上部的攔截器鏈將被斷開, 後續的處理器以及對於的postHandle()

都無法執行, 只有已經執行通過的攔截器的afterCompletion()方法會執行.

實際運用

  • 許可權校驗: 判斷當前請求是否登陸, 若未登入或者無許可權, 返回對應的介面.
  • 效能監控: 監控系統指定方法執行的時間, 尋找系統性能調優點.
  • 日誌列印: 記錄請求日誌, 用於系統監控, 資訊統計與分析等等.
  • ......