首頁 > 軟體

SpringBoot2零基礎到精通之例外處理與web原生元件注入

2022-03-22 13:00:05

1 例外處理

  預設情況下,SpringBoot會提供/error處理所有的錯誤請求並返回相應的資訊,對於瀏覽器使用者端來說會返回一個包含時間戳、狀態碼、錯誤資訊、攜帶的自定義異常資訊、發生錯誤的路徑等資訊的錯誤Whitelabel頁面,對於機器使用者端(postman等)會返回一個包含以上內容的JSON資料

1.1 例外處理之錯誤頁面

  要想替代之前瀏覽器使用者端返回的錯誤Whitelabel頁面,需要將自定義的html頁面放在靜態資源static等的error資料夾下或者模板引擎templates的error資料夾下,這樣的話出現錯誤時SpringBoot傳送/error請求就會自動解析這些頁面進行渲染。頁面解析規則:先將狀態碼的值與error資料夾下的頁面名進行精確匹配,如果精確匹配不到的話就按照4xx、5xx這樣的方式進行模糊匹配,要是還匹配不到的話就返回Whitelabel頁面

1.2 例外處理之精確捕獲

  要是說錯誤頁面是按照狀態碼進行頁面處理的話,精確捕獲就是通過異常類進行捕獲,捕獲之後再進行一系列的自定義操作。具體步驟就是:建立一個例外處理器類,並在類上加@ControllerAdvice註解表明是一個例外處理器並向容器中註冊該元件,@ExceptionHandler註解對引數中的異常類進行精準捕獲,並在方法體定義具體的處理操作。

@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler({ArithmeticException.class, NullPointerException.class})
    public String handleArithException(Exception e) {
        log.info("系統捕獲到異常資訊:{}", e);
        return "login";
    }
}

1.3 例外處理之自定義異常

  有時候我們需要在程式中自定義一些執行時異常,這些異常並不會像那些異常一樣產生異常狀態碼,甚至在未定義之前都不算是異常且不會影響程式的正常執行。這時就需要我們自定義異常的產生邏輯,並自定義異常類建立有參無參構造器,在類上加@ResponseStatus註解,使用註解引數定義異常響應碼和異常資訊

@ResponseStatus(value = HttpStatus.FORBIDDEN, reason = "使用者數量太多")
public class UserTooManyException extends RuntimeException{

    public UserTooManyException() {

    }
    public UserTooManyException(String message) {
        super(message);
    }
}

異常產生邏輯:

// 判斷使用者數量丟擲使用者數量過多的自定義異常
if (users.size() > 3) {
    throw new UserTooManyException();
}

1.4 例外處理之框架底層異常

  除了exception類中定義的異常外,spring框架底層也定義了一些異常,這些異常由DefaultHandlerExceptionResolver來處理

2 web原生元件的注入

2.1 servlet元件

  servlet元件需要自定義建立一個servlet類繼承HttpServlet,並使用@WebServlet註解的urlPatterns屬性宣告攔截的請求,再通過主程式類上使用@ServletComponentScan(basePackages = 「…」)註解將該元件掃描註冊到容器中。

// 宣告攔截的請求
@WebServlet(urlPatterns = "/my")
public class MyServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("385695");
    }
}

2.2 filter元件

  filter元件需要自定義建立一個filter類實現Filter介面,並使用@WebFilter註解的urlPatterns屬性宣告過濾的請求

@Slf4j
@WebFilter(urlPatterns = {"/css/*", "/images/*"})
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("MyFilter初始化……");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("MyFilter方法開始工作了……");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        log.info("MyFilter銷燬了……");
    }
}

2.3 listener元件

  listener元件需要自定義建立一個listener類實現ServletContextListener 介面,並使用@WebListener註解

@Slf4j
@WebListener
public class MyServletContextListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        log.info("MyServletContextListener監聽到專案初始化完成……");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        log.info("MyServletContextListener監聽到專案已經銷燬……");
    }
}

除了使用註解進行註冊之外,還可以使用設定類的方式將以上三種元件註冊到容器中去

@Configuration
public class MyRegistConfig {

    @Bean
    public ServletRegistrationBean MyServlet() {
        MyServlet myServlet = new MyServlet();
        return new ServletRegistrationBean(myServlet, "/my", "/my02");
    }


    @Bean
    public FilterRegistrationBean myFilter() {
        MyFilter myFilter = new MyFilter();
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(myFilter);
        filterRegistrationBean.setUrlPatterns(Arrays.asList("/my", "/my02"));
        return filterRegistrationBean;
    }

    @Bean
    public ServletListenerRegistrationBean myListener() {
        MyServletContextListener listener = new MyServletContextListener();
        return new ServletListenerRegistrationBean(listener);
    }
}

  通過servlet元件宣告的/my請求並不會經過spring的攔截器攔截處理,而是直接交由tomcat伺服器進行處理:現在有這麼兩個元件攔截到我們傳送的/my請求,一個是spring的元件DispatcherServlet通過/路徑攔截到,一個是tomcat的自定義MyServlet元件通過/my路徑攔截到。tomcat伺服器對請求有這麼一個處理規則,當多個servlet元件都能處理到同一個請求的時候,使用匹配度最高的元件進行處理,也就是說處理請求的是tomcat的MyServlet元件。

3 web實現客製化化總結

  • 建立設定類實現WebMvcConfigurer介面,重寫相應的方法或者使用@Bean註解向容器中擴充套件功能(使用的最多)
  • 自定義設定類使用@Bean註解使用自定義的web原生元件替換容器中的預設元件或者向容器中新增元件
  • 組態檔的設定項修改
  • xxxCustomizer@EnableWebMvc註解表示全面接管SpringMVC,導致的效果就是SpringBoot的所有自動設定全部失效,全部功能都需要自己進行設定。大佬專屬註解,小白的禁術!!!

到此這篇關於SpringBoot2零基礎到精通之例外處理與web原生元件注入的文章就介紹到這了,更多相關SpringBoot2 例外處理內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com