SpringMVC中的異常處理機(jī)制詳解
1. 概述
SpringMVC提供了基于xml和基于注解的異常處理機(jī)制,一般情況下兩者都要進(jìn)行配置,xml異常處理機(jī)制主要用于處理xml方式產(chǎn)生的異常,注解異常處理機(jī)制主要用于處理基于注解方式產(chǎn)生的異常。
2. 基于xml方式的異常處理機(jī)制
<!--配置基于xml的異常映射--> <bean id="simpleMappingExceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <!--key屬性指定具體的出錯(cuò)類型,標(biāo)簽體中為對(duì)應(yīng)的出錯(cuò)頁面(這個(gè)值會(huì)拼上前后綴以得到全路徑)--> <prop key="java.lang.Exception">system-error</prop> </props> </property> </bean>
3. 基于注解方式的異常處理
步驟:
- 使用@ControllerAdvice注解表名此類為異常處理類
- 方法上使用@ExceptionHandler注解表示此方法處理何種異常,如
@ExceptionHandler(value = ArithmeticException.class)
4. 實(shí)際應(yīng)用
一般若是普通請(qǐng)求產(chǎn)生的異常,則應(yīng)該返回錯(cuò)誤頁面,若是Ajax請(qǐng)求返回的是相應(yīng)的JSON字符串。
判斷一個(gè)請(qǐng)求是否是Ajax請(qǐng)求
請(qǐng)求依據(jù):(兩者含其一則為Ajax請(qǐng)求)
- 請(qǐng)求頭中Accept中包含application/json
- 請(qǐng)求頭中X-Requested-With字段為XMLHttpRequest的為Ajax請(qǐng)求
/** * 判斷此次請(qǐng)求是否是Ajax請(qǐng)求 * @param request 此次請(qǐng)求對(duì)應(yīng)的request對(duì)象 * @return true表示是Ajax請(qǐng)求,false表示是普通請(qǐng)求 */ public static boolean isAjax(HttpServletRequest request) { String accept = request.getHeader("Accept"); String xRequestHeader = request.getHeader("X-Requested-With"); return accept != null && accept.contains("application/json") || xRequestHeader != null && xRequestHeader.equals("XMLHttpRequest"); }
配置基于xml方式的異常處理機(jī)制
配置基于注解方式的異常處理
package com.wuw.crowd.mvc.config; import com.google.gson.Gson; import com.wuw.crowd.exception.LoginFailedException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.servlet.ModelAndView; import com.wuw.crowd.util.CrowdUtil; import com.wuw.crowd.constant.CrowdConstant; import com.wuw.crowd.util.ResultEntity; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * @description: 基于注解的異常處理機(jī)制 * @author: WuW * @create: 2022/5/2 18:36 */ @ControllerAdvice public class MyExceptionResolver { @ExceptionHandler(value = ArithmeticException.class) public ModelAndView resolveArithmeticException(HttpServletRequest request, HttpServletResponse response, NullPointerException exception) throws IOException { String viewName = "system-error"; return commonResolve(viewName, exception, request, response); } @ExceptionHandler(value = NullPointerException.class) public ModelAndView resolveNullPointerException(HttpServletRequest request, HttpServletResponse response, NullPointerException exception) throws IOException { String viewName = "system-error"; return commonResolve(viewName, exception, request, response); } @ExceptionHandler(value = LoginFailedException.class) public ModelAndView resolveLoginFailedException(HttpServletRequest request, HttpServletResponse response, LoginFailedException exception) throws IOException { String viewName = "admin-login"; return commonResolve(viewName, exception, request, response); } /** * 抽取異常處理機(jī)制的公共部分 * @param viewName 將要返回到哪個(gè)頁面 * @param exception 捕獲到的異常信息 * @param request 請(qǐng)求對(duì)象 * @param response 響應(yīng)對(duì)象 * @return 返回ModelAndView * @throws IOException 響應(yīng)對(duì)象獲取輸出流時(shí)拋出異常 */ private ModelAndView commonResolve(String viewName, Exception exception, HttpServletRequest request, HttpServletResponse response) throws IOException { boolean ajax = CrowdUtil.isAjax(request); // 如果是Ajax請(qǐng)求 if (ajax) { // 創(chuàng)建ResultEntity對(duì)象 ResultEntity<Object> failed = ResultEntity.failed(exception.getMessage()); Gson gson = new Gson(); // 將ResultEntity對(duì)象轉(zhuǎn)換為JSON字符串 String s = gson.toJson(failed); // 將JSON字符串作為響應(yīng)體返回給瀏覽器 response.getWriter().write(s); return null; } // 如果是普通請(qǐng)求 ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject(CrowdConstant.ATTR_NAME_EXCEPTION, exception); // 設(shè)置對(duì)應(yīng)的視圖名稱 modelAndView.setViewName(viewName); return modelAndView; } }
注:ResultEntity對(duì)象為統(tǒng)一響應(yīng)對(duì)象,其中的failed方法實(shí)際上是將傳入的exception對(duì)象封裝成一個(gè)ResultEntity對(duì)象并返回給調(diào)用者。CrowdConstant類為自定義的常量類,主要用于存儲(chǔ)各種常用的字符串,可有效預(yù)防寫錯(cuò)單詞導(dǎo)致的程序錯(cuò)誤,在實(shí)際開發(fā)中十分有用。
解釋:若為Ajax請(qǐng)求,則應(yīng)該向?yàn)g覽器返回一個(gè)JSON字符串格式的ResultEntity對(duì)象,此時(shí)異常處理機(jī)制返回null即可;若為普通請(qǐng)求,則拋出異常,并返回異常頁面(此時(shí)是頁面名稱,因?yàn)榍昂缶Y在mvc文件中已配置)。
到此這篇關(guān)于SpringMVC中的異常處理機(jī)制的文章就介紹到這了,更多相關(guān)SpringMVC異常處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Boot實(shí)戰(zhàn)之?dāng)?shù)據(jù)庫操作的示例代碼
本篇文章主要介紹了Spring Boot實(shí)戰(zhàn)之?dāng)?shù)據(jù)庫操作的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-01-01Java統(tǒng)計(jì)50個(gè)10到50之間整數(shù)的隨機(jī)出現(xiàn)次數(shù)
這篇文章主要為大家詳細(xì)介紹了Java統(tǒng)計(jì)50個(gè)10到50之間整數(shù)的隨機(jī)出現(xiàn)次數(shù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07Spring?Security實(shí)現(xiàn)基于RBAC的權(quán)限表達(dá)式動(dòng)態(tài)訪問控制的操作方法
這篇文章主要介紹了Spring?Security實(shí)現(xiàn)基于RBAC的權(quán)限表達(dá)式動(dòng)態(tài)訪問控制,資源權(quán)限表達(dá)式動(dòng)態(tài)權(quán)限控制在Spring Security也是可以實(shí)現(xiàn)的,首先開啟方法級(jí)別的注解安全控制,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-04-04java實(shí)現(xiàn)http的Post、Get、代理訪問請(qǐng)求
這篇文章主要為大家提供了java實(shí)現(xiàn)http的Post、Get、代理訪問請(qǐng)求的相關(guān)代碼,感興趣的小伙伴們可以參考一下2016-01-01舉例講解Java的Jackson庫中ObjectMapper類的使用
這篇文章主要介紹了舉例講解Java的Jackson庫中ObjectMapper類的使用,Jackson庫通常被用來實(shí)現(xiàn)Java的對(duì)象和JSON之間的轉(zhuǎn)換功能,需要的朋友可以參考下2016-01-01Java中String判斷值為null或空及地址是否相等的問題
這篇文章主要介紹了Java中String判斷值為null或空及地址是否相等的問題,文中舉了簡(jiǎn)單的例子對(duì)字符串類型的值和地址問題進(jìn)行講解,需要的朋友可以參考下2016-01-01Maven添加Tomcat插件實(shí)現(xiàn)熱部署代碼實(shí)例
這篇文章主要介紹了Maven添加Tomcat插件實(shí)現(xiàn)熱部署代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04spring boot啟動(dòng)出現(xiàn)Unable to start ServletWe
在使用SpringBoot時(shí),啟動(dòng)報(bào)錯(cuò)可能源于多種原因,錯(cuò)誤提示為缺少ServletWebServerFactory bean,初步分析可能是缺少spring-boot-starter-web依賴或@EnableAutoConfiguration注解,感興趣的可以了解一下2024-10-10