SpringBoot2零基礎(chǔ)到精通之異常處理與web原生組件注入
1 異常處理
??默認(rèn)情況下,SpringBoot會(huì)提供/error處理所有的錯(cuò)誤請(qǐng)求并返回相應(yīng)的信息,對(duì)于瀏覽器客戶端來(lái)說(shuō)會(huì)返回一個(gè)包含時(shí)間戳、狀態(tài)碼、錯(cuò)誤信息、攜帶的自定義異常信息、發(fā)生錯(cuò)誤的路徑等信息的錯(cuò)誤Whitelabel頁(yè)面,對(duì)于機(jī)器客戶端(postman等)會(huì)返回一個(gè)包含以上內(nèi)容的JSON數(shù)據(jù)
1.1 異常處理之錯(cuò)誤頁(yè)面
??要想替代之前瀏覽器客戶端返回的錯(cuò)誤Whitelabel頁(yè)面,需要將自定義的html頁(yè)面放在靜態(tài)資源static等的error文件夾下或者模板引擎templates的error文件夾下,這樣的話出現(xiàn)錯(cuò)誤時(shí)SpringBoot發(fā)送/error請(qǐng)求就會(huì)自動(dòng)解析這些頁(yè)面進(jìn)行渲染。頁(yè)面解析規(guī)則:先將狀態(tài)碼的值與error文件夾下的頁(yè)面名進(jìn)行精確匹配,如果精確匹配不到的話就按照4xx、5xx這樣的方式進(jìn)行模糊匹配,要是還匹配不到的話就返回Whitelabel頁(yè)面
1.2 異常處理之精確捕獲
??要是說(shuō)錯(cuò)誤頁(yè)面是按照狀態(tài)碼進(jìn)行頁(yè)面處理的話,精確捕獲就是通過(guò)異常類(lèi)進(jìn)行捕獲,捕獲之后再進(jìn)行一系列的自定義操作。具體步驟就是:創(chuàng)建一個(gè)異常處理器類(lèi),并在類(lèi)上加@ControllerAdvice注解表明是一個(gè)異常處理器并向容器中注冊(cè)該組件,@ExceptionHandler注解對(duì)參數(shù)中的異常類(lèi)進(jìn)行精準(zhǔn)捕獲,并在方法體定義具體的處理操作。
@Slf4j @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler({ArithmeticException.class, NullPointerException.class}) public String handleArithException(Exception e) { log.info("系統(tǒng)捕獲到異常信息:{}", e); return "login"; } }
1.3 異常處理之自定義異常
??有時(shí)候我們需要在程序中自定義一些運(yùn)行時(shí)異常,這些異常并不會(huì)像那些異常一樣產(chǎn)生異常狀態(tài)碼,甚至在未定義之前都不算是異常且不會(huì)影響程序的正常運(yùn)行。這時(shí)就需要我們自定義異常的產(chǎn)生邏輯,并自定義異常類(lèi)創(chuàng)建有參無(wú)參構(gòu)造器,在類(lèi)上加@ResponseStatus注解,使用注解參數(shù)定義異常響應(yīng)碼和異常信息
@ResponseStatus(value = HttpStatus.FORBIDDEN, reason = "用戶數(shù)量太多") public class UserTooManyException extends RuntimeException{ public UserTooManyException() { } public UserTooManyException(String message) { super(message); } }
異常產(chǎn)生邏輯:
// 判斷用戶數(shù)量拋出用戶數(shù)量過(guò)多的自定義異常 if (users.size() > 3) { throw new UserTooManyException(); }
1.4 異常處理之框架底層異常
??除了exception類(lèi)中定義的異常外,spring框架底層也定義了一些異常,這些異常由DefaultHandlerExceptionResolver來(lái)處理
2 web原生組件的注入
2.1 servlet組件
??servlet組件需要自定義創(chuàng)建一個(gè)servlet類(lèi)繼承HttpServlet,并使用@WebServlet注解的urlPatterns屬性聲明攔截的請(qǐng)求,再通過(guò)主程序類(lèi)上使用@ServletComponentScan(basePackages = “…”)注解將該組件掃描注冊(cè)到容器中。
// 聲明攔截的請(qǐng)求 @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組件需要自定義創(chuàng)建一個(gè)filter類(lèi)實(shí)現(xiàn)Filter接口,并使用@WebFilter注解的urlPatterns屬性聲明過(guò)濾的請(qǐng)求
@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方法開(kāi)始工作了……"); filterChain.doFilter(servletRequest, servletResponse); } @Override public void destroy() { log.info("MyFilter銷(xiāo)毀了……"); } }
2.3 listener組件
??listener組件需要自定義創(chuàng)建一個(gè)listener類(lèi)實(shí)現(xiàn)ServletContextListener 接口,并使用@WebListener注解
@Slf4j @WebListener public class MyServletContextListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { log.info("MyServletContextListener監(jiān)聽(tīng)到項(xiàng)目初始化完成……"); } @Override public void contextDestroyed(ServletContextEvent sce) { log.info("MyServletContextListener監(jiān)聽(tīng)到項(xiàng)目已經(jīng)銷(xiāo)毀……"); } }
除了使用注解進(jìn)行注冊(cè)之外,還可以使用配置類(lèi)的方式將以上三種組件注冊(cè)到容器中去
@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); } }
??通過(guò)servlet組件聲明的/my請(qǐng)求并不會(huì)經(jīng)過(guò)spring的攔截器攔截處理,而是直接交由tomcat服務(wù)器進(jìn)行處理:現(xiàn)在有這么兩個(gè)組件攔截到我們發(fā)送的/my請(qǐng)求,一個(gè)是spring的組件DispatcherServlet通過(guò)/路徑攔截到,一個(gè)是tomcat的自定義MyServlet組件通過(guò)/my路徑攔截到。tomcat服務(wù)器對(duì)請(qǐng)求有這么一個(gè)處理規(guī)則,當(dāng)多個(gè)servlet組件都能處理到同一個(gè)請(qǐng)求的時(shí)候,使用匹配度最高的組件進(jìn)行處理,也就是說(shuō)處理請(qǐng)求的是tomcat的MyServlet組件。
3 web實(shí)現(xiàn)定制化總結(jié)
- 創(chuàng)建配置類(lèi)實(shí)現(xiàn)WebMvcConfigurer接口,重寫(xiě)相應(yīng)的方法或者使用@Bean注解向容器中擴(kuò)展功能(使用的最多)
- 自定義配置類(lèi)使用@Bean注解使用自定義的web原生組件替換容器中的默認(rèn)組件或者向容器中添加組件
- 配置文件的配置項(xiàng)修改
- xxxCustomizer@EnableWebMvc注解表示全面接管SpringMVC,導(dǎo)致的效果就是SpringBoot的所有自動(dòng)配置全部失效,全部功能都需要自己進(jìn)行配置。大佬專屬注解,小白的禁術(shù)?。?!
到此這篇關(guān)于SpringBoot2零基礎(chǔ)到精通之異常處理與web原生組件注入的文章就介紹到這了,更多相關(guān)SpringBoot2 異常處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring?Boot實(shí)現(xiàn)配置文件的自動(dòng)加載和刷新功能
這篇文章我們介紹了Spring?Boot如何實(shí)現(xiàn)配置文件的自動(dòng)加載和刷新,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2023-05-05Arrays.sort如何實(shí)現(xiàn)降序排序
這篇文章主要介紹了Arrays.sort如何實(shí)現(xiàn)降序排序問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11解決Springboot配置excludePathPatterns不生效的問(wèn)題
這篇文章主要介紹了解決Springboot配置excludePathPatterns不生效的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10java 8 lambda表達(dá)式list操作分組、過(guò)濾、求和、最值、排序、去重代碼詳解
java8的lambda表達(dá)式提供了一些方便list操作的方法,主要涵蓋分組、過(guò)濾、求和、最值、排序、去重,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-01-01Java線程Timer定時(shí)器用法詳細(xì)總結(jié)
在本篇文章里小編給大家整理的是關(guān)于Java線程Timer定時(shí)器用法詳細(xì)總結(jié)內(nèi)容,需要的朋友們學(xué)習(xí)下吧。2020-02-02淺談Java實(shí)現(xiàn)回溯算法之八皇后問(wèn)題
八皇后問(wèn)題是一個(gè)古老而又著名的問(wèn)題,是學(xué)習(xí)回溯算法的一個(gè)經(jīng)典案例。今天我們就一起來(lái)探究一下吧2021-06-06java8 stream自定義分組求和并排序的實(shí)現(xiàn)
這篇文章主要介紹了java8 stream自定義分組求和并排序的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01Java爬蟲(chóng) 信息抓取的實(shí)現(xiàn)
本文主要介紹 Java爬蟲(chóng) 信息抓取的實(shí)現(xiàn),這里詳細(xì)介紹了如何實(shí)現(xiàn)該方法,并附示例代碼供大家學(xué)習(xí)參考,有興趣的小伙伴可以參考下2016-09-09