SpringBoot起飛系列-攔截器和統一錯誤處理(七)


一、前言

在前邊部分我們已經學會了基本的web開發流程,在web開發中,我們通常會對請求做統一處理,比如未登錄的用戶要攔截掉相關請求,報錯頁面統一顯示等等,這些都需要配置,可以大大簡化我們的代碼,實現功能的完整性與統一性。

二、攔截器配置

首先我們先做一個登錄身份驗證攔截器,來攔截那些沒有登錄的用戶,保護我們的資源。下面我們創建一個攔截器,需要實現攔截器接口。

 1 package com.example.demo.component;
 2 
 3 import org.springframework.web.servlet.HandlerInterceptor;
 4 import org.springframework.web.servlet.ModelAndView;
 5 
 6 import javax.servlet.http.HttpServletRequest;
 7 import javax.servlet.http.HttpServletResponse;
 8 
 9 public class LoginHandlerInterceptor implements HandlerInterceptor {
10 
11     @Override
12     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
13         if(request.getSession().getAttribute("loginUser") == null){
14             request.setAttribute("msg","請先登錄");
15             request.getRequestDispatcher("/index.html").forward(request,response);
16             return false;
17         }
18         return true;
19     }
20 
21     @Override
22     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
23 
24     }
25 
26     @Override
27     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
28 
29     }
30 }

這個攔截器的作用是獲取當前session中的loginUser屬性,如果有值說明登錄了就可以放行,當然我們需要在登錄成功的代碼里邊設置好session的這個屬性。

在WebConfig中添加我們的攔截器:

 1     //所有的WebMvcConfigurerAdapter組件都會一起起作用
 2     @Bean //將組件注冊在容器
 3     public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){
 4         WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter() {
 5             @Override
 6             public void addViewControllers(ViewControllerRegistry registry) {
 7                 registry.addViewController("/").setViewName("login");
 8                 registry.addViewController("/index.html").setViewName("login");
 9             }
10 
11             @Override
12             public void addInterceptors(InterceptorRegistry registry) {
13                 registry.addInterceptor(new LoginHandlerInterceptor())
14                         .excludePathPatterns("/index.html","/","/user/login");
15             }
16         };
17         return adapter;
18     }

第12-15行,注冊我們攔截器之后,排除掉不需要驗證的頁面,默認情況下靜態資源不會做驗證。

三、統一錯誤處理

springboot默認已經配置了統一錯誤處理,只不過錯誤頁面是內置的,可能不是我們想要的,所以如果我們要自定義錯誤頁面,還得重新配置。

3.1 定制錯誤頁面

在使用模板的情況下,springboot默認會找到/templates/error/xxx.html頁面作為錯誤頁面顯示,比如我們用4xx.html處理所有httpstatuscode以4開頭的錯誤,比如401,403,404,如果有具體的數字,就先用具體的數字對應頁面,如果沒有就用有前綴開頭的頁面。

顯示錯誤頁面時,頁面上能獲取到以下信息,可以讓我們看到詳細的錯誤信息:

timestamp:時間戳。

status:狀態碼。

error:錯誤提示。

exception:異常對象。

message:異常消息。

errors:JSR303數據校驗的錯誤都在這里。

在沒有模板的情況下,會去找靜態資源下的相關頁面,如果靜態資源下也沒有,就用springboot默認的錯誤頁面。如下,我添加了一個4xx.html的錯誤處理頁面,當我訪問一個不存在的路徑(404錯誤)時,就會顯示我添加的4xx.html頁面:

3.2 自定義返回的json數據

默認情況下springboot會出現自適應的錯誤顯示,當用瀏覽器訪問(接受類型為text/html)時會顯示錯誤頁面,當用postman(接受類型為application/json)會顯示錯誤json數據。不過顯示的字段都是內置固定的,如果我們想要添加自己的錯誤數據,就要自己定制了。

在springboot中,出現錯誤以后,會來到/error請求,會被BasicErrorController處理,響應出去可以獲取的數據是由getErrorAttributes得到的(是AbstractErrorController(ErrorController)規定的方法),這里我們就可以編寫一個ErrorController的實現類【或者是編寫AbstractErrorController的子類】,放在容器中替換掉原來的ErrorController,頁面上能用的數據,或者是json返回能用的數據都是通過errorAttributes.getErrorAttributes得到。

添加自定一個ErrorAttribute,重寫errorAttributes.getErrorAttributes,返回自己的數據map:

 1 package com.example.demo.component;
 2 
 3 import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
 4 import org.springframework.stereotype.Component;
 5 import org.springframework.web.context.request.WebRequest;
 6 
 7 import java.util.Map;
 8 
 9 @Component
10 public class MyErrorAttributes extends DefaultErrorAttributes {
11     @Override
12     public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
13         Map<String, Object> map =  super.getErrorAttributes(webRequest, includeStackTrace);
14         map.put("code",1);
15         map.put("msg","自定義錯誤");
16         return map;
17     }
18 }

訪問錯誤頁面和json返回:

四、總結

不得不說,springboot真是很懂我們,把所有東西都配置好了,只要我們稍微修修補補就能很好的滿足我們的需求了,這里我們可以完全不要原始的錯誤信息,可以把錯誤信息獲取數據組裝成我們標准統一格式的錯誤信息,也可以在這里統一記錄我們的錯誤日志,也是非常的方便。


免責聲明!

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



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