SpringBoot搭建全局異常攔截
1.異常攔截類的創(chuàng)建
package com.liqi.web.core.exception; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestControllerAdvice; import com.liqi.common.base.Constants; import com.liqi.common.base.ResultBean; import com.liqi.common.exception.BusinessInterfaceException; import com.liqi.common.exception.bean.ErrorBean; import lombok.extern.slf4j.Slf4j; /** * 自定義異常處理器 * * @author ieflex */ @RestControllerAdvice @Slf4j public class InterfaceExceptionHandler { /** * 接口 業(yè)務(wù)異常 */ @ResponseBody @ExceptionHandler(BusinessInterfaceException.class) public String businessInterfaceException(BusinessInterfaceException e) { log.error(e.getMessage(), e); ErrorBean error = e.getError(); ResultBean resultBean = new ResultBean(error.hashCode(), error.getErrorMsg()); return resultBean.toString(); } /** * 攔截所有運(yùn)行時(shí)的全局異常 */ @ExceptionHandler(RuntimeException.class) @ResponseBody public String runtimeException(RuntimeException e) { log.error(e.getMessage(), e); // 返回 JOSN ResultBean resultBean = new ResultBean(Constants.INTERFACE_MSG_301, Constants.INTERFACE_MSG_301_TEXT); return resultBean.toString(); } /** * 系統(tǒng)異常捕獲處理 */ @ExceptionHandler(Exception.class) @ResponseBody public String exception(Exception e) { log.error(e.getMessage(), e); ResultBean resultBean = new ResultBean(Constants.INTERFACE_MSG_301, Constants.INTERFACE_MSG_301_TEXT); // 返回 JOSN return resultBean.toString(); } }
2.controller 測(cè)試
package com.springboot_Error.ErrorController; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class ErrorControllerTest { //全局異常攔截 測(cè)試 @RequestMapping("/ErrorTest") public String index2(){ System.err.println("請(qǐng)求成功!"); int i = 1/0; //這里會(huì)有一個(gè)運(yùn)算異常 return "index"; } }
3.啟動(dòng) springboot 工程
package com.springboot_Error.ErrorRun; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.ComponentScan; //掃描 com.springboot_Error.ErrorController 包下 controller 注解過(guò)的類 @ComponentScan(basePackages={"com.springboot_Error.ErrorController"}) @EnableAutoConfiguration public class ErrorRun { public static void main(String[] args) { SpringApplication.run(ErrorRun.class, args); } }
4.測(cè)試
/** * 功能描述: 模擬自定義異常 * @return */ @RequestMapping(value = "/api/test") public Object myext() { throw new BusinessInterfaceException("500", "my ext異常"); }
經(jīng)過(guò)測(cè)試發(fā)現(xiàn)可以捕獲到Controller層的異常,當(dāng)前前提是Controller層沒(méi)有對(duì)異常進(jìn)行catch處理,如果Controller層對(duì)異常進(jìn)行了catch處理,那么在這里就不會(huì)捕獲到Controller層的異常了,所以這一點(diǎn)要注意。
5.基于Springboot自身的全局異常統(tǒng)一處理
主要是實(shí)現(xiàn)ErrorController接口或者繼承AbstractErrorController抽象類或者繼承BasicErrorController類
以下是網(wǎng)上一位博主給出的示例代碼,博客地址為:https://blog.csdn.net/king_is_everyone/article/details/53080851
@Controller @RequestMapping(value = "error") @EnableConfigurationProperties({ServerProperties.class}) public class ExceptionController implements ErrorController { private ErrorAttributes errorAttributes; @Autowired private ServerProperties serverProperties; /** * 初始化ExceptionController * @param errorAttributes */ @Autowired public ExceptionController(ErrorAttributes errorAttributes) { Assert.notNull(errorAttributes, "ErrorAttributes must not be null"); this.errorAttributes = errorAttributes; } /** * 定義404的ModelAndView * @param request * @param response * @return */ @RequestMapping(produces = "text/html",value = "404") public ModelAndView errorHtml404(HttpServletRequest request, HttpServletResponse response) { response.setStatus(getStatus(request).value()); Map<String, Object> model = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.TEXT_HTML)); return new ModelAndView("error/404", model); } /** * 定義404的JSON數(shù)據(jù) * @param request * @return */ @RequestMapping(value = "404") @ResponseBody public ResponseEntity<Map<String, Object>> error404(HttpServletRequest request) { Map<String, Object> body = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.TEXT_HTML)); HttpStatus status = getStatus(request); return new ResponseEntity<Map<String, Object>>(body, status); } /** * 定義500的ModelAndView * @param request * @param response * @return */ @RequestMapping(produces = "text/html",value = "500") public ModelAndView errorHtml500(HttpServletRequest request, HttpServletResponse response) { response.setStatus(getStatus(request).value()); Map<String, Object> model = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.TEXT_HTML)); return new ModelAndView("error/500", model); } /** * 定義500的錯(cuò)誤JSON信息 * @param request * @return */ @RequestMapping(value = "500") @ResponseBody public ResponseEntity<Map<String, Object>> error500(HttpServletRequest request) { Map<String, Object> body = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.TEXT_HTML)); HttpStatus status = getStatus(request); return new ResponseEntity<Map<String, Object>>(body, status); } /** * Determine if the stacktrace attribute should be included. * @param request the source request * @param produces the media type produced (or {@code MediaType.ALL}) * @return if the stacktrace attribute should be included */ protected boolean isIncludeStackTrace(HttpServletRequest request, MediaType produces) { ErrorProperties.IncludeStacktrace include = this.serverProperties.getError().getIncludeStacktrace(); if (include == ErrorProperties.IncludeStacktrace.ALWAYS) { return true; } if (include == ErrorProperties.IncludeStacktrace.ON_TRACE_PARAM) { return getTraceParameter(request); } return false; } /** * 獲取錯(cuò)誤的信息 * @param request * @param includeStackTrace * @return */ private Map<String, Object> getErrorAttributes(HttpServletRequest request, boolean includeStackTrace) { RequestAttributes requestAttributes = new ServletRequestAttributes(request); return this.errorAttributes.getErrorAttributes(requestAttributes, includeStackTrace); } /** * 是否包含trace * @param request * @return */ private boolean getTraceParameter(HttpServletRequest request) { String parameter = request.getParameter("trace"); if (parameter == null) { return false; } return !"false".equals(parameter.toLowerCase()); } /** * 獲取錯(cuò)誤編碼 * @param request * @return */ private HttpStatus getStatus(HttpServletRequest request) { Integer statusCode = (Integer) request .getAttribute("javax.servlet.error.status_code"); if (statusCode == null) { return HttpStatus.INTERNAL_SERVER_ERROR; } try { return HttpStatus.valueOf(statusCode); } catch (Exception ex) { return HttpStatus.INTERNAL_SERVER_ERROR; } } /** * 實(shí)現(xiàn)錯(cuò)誤路徑,暫時(shí)無(wú)用 * @see ExceptionMvcAutoConfiguration#containerCustomizer() * @return */ @Override public String getErrorPath() { return ""; } }
6.AOP也可以實(shí)現(xiàn)異常的全局處理
@Component @Aspect public class ExceptionAspectController { public static final Logger logger = LoggerFactory.getLogger(ExceptionAspectController.class); @Pointcut("execution(* com.test.test.*.*(..))")//此處基于自身項(xiàng)目的路徑做具體的設(shè)置 public void pointCut(){} @Around("pointCut()") public Object handleControllerMethod(ProceedingJoinPoint pjp) { Stopwatch stopwatch = Stopwatch.createStarted(); APIResponse<?> apiResponse; try { logger.info("執(zhí)行Controller開(kāi)始: " + pjp.getSignature() + " 參數(shù):" + Lists.newArrayList(pjp.getArgs()).toString()); apiResponse = (APIResponse<?>) pjp.proceed(pjp.getArgs()); logger.info("執(zhí)行Controller結(jié)束: " + pjp.getSignature() + ", 返回值:" + apiResponse.toString()); logger.info("耗時(shí):" + stopwatch.stop().elapsed(TimeUnit.MILLISECONDS) + "(毫秒)."); } catch (Throwable throwable) { apiResponse = handlerException(pjp, throwable); } return apiResponse; } private APIResponse<?> handlerException(ProceedingJoinPoint pjp, Throwable e) { APIResponse<?> apiResponse = null; if(e.getClass().isAssignableFrom(MessageCenterException.class) ){ MessageCenterException messageCenterException = (MessageCenterException)e; logger.error("RuntimeException{方法:" + pjp.getSignature() + ", 參數(shù):" + pjp.getArgs() + ",異常:" + messageCenterException.getException().getMessage() + "}", e); apiResponse = messageCenterException.getApiResponse(); } else if (e instanceof RuntimeException) { logger.error("RuntimeException{方法:" + pjp.getSignature() + ", 參數(shù):" + pjp.getArgs() + ",異常:" + e.getMessage() + "}", e); apiResponse = new APIResponse(APIResponse.FAIL,null,e.getMessage()); } else { logger.error("異常{方法:" + pjp.getSignature() + ", 參數(shù):" + pjp.getArgs() + ",異常:" + e.getMessage() + "}", e); apiResponse = new APIResponse(APIResponse.FAIL,null,e.getMessage()); } return apiResponse; } }
到此這篇關(guān)于SpringBoot搭建全局異常攔截的文章就介紹到這了,更多相關(guān)Springboot全局異常內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Springboot?過(guò)濾器、攔截器、全局異常處理的方案處理小結(jié)
- SpringBoot全局異常處理機(jī)制和配置攔截器方式
- SpringBoot結(jié)果封裝和異常攔截的實(shí)現(xiàn)示例
- SpringBoot切面攔截@PathVariable參數(shù)及拋出異常的全局處理方式
- springboot攔截器過(guò)濾token,并返回結(jié)果及異常處理操作
- SpringBoot @ControllerAdvice 攔截異常并統(tǒng)一處理
- Spring boot項(xiàng)目中異常攔截設(shè)計(jì)和處理詳解
- Spring Boot統(tǒng)一異常攔截實(shí)踐指南(最新推薦)
相關(guān)文章
@RequestParam使用defaultValue屬性設(shè)置默認(rèn)值的操作
這篇文章主要介紹了@RequestParam使用defaultValue屬性設(shè)置默認(rèn)值的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-02-02JavaScript實(shí)現(xiàn)鼠標(biāo)移動(dòng)粒子跟隨效果
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)鼠標(biāo)移動(dòng)粒子跟隨效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08Springboot配置suffix指定mvc視圖的后綴方法
這篇文章主要介紹了Springboot配置suffix指定mvc視圖的后綴方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07mybatis-plus實(shí)體類主鍵策略有3種(小結(jié))
這篇文章主要介紹了mybatis-plus實(shí)體類主鍵策略有3種(小結(jié)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08Java使用自定義注解+反射實(shí)現(xiàn)字典轉(zhuǎn)換代碼實(shí)例
這篇文章主要介紹了Java使用自定義注解+反射實(shí)現(xiàn)字典轉(zhuǎn)換代碼實(shí)例,注解是一種能被添加到j(luò)ava代碼中的元數(shù)據(jù),類、方法、變量、參數(shù)和包都可以用注解來(lái)修飾,注解對(duì)于它所修飾的代碼并沒(méi)有直接的影響,需要的朋友可以參考下2023-09-09Java類的序列化版本唯一標(biāo)識(shí)符serialVersionUID使用
serialVersionUID是一個(gè)類的序列化版本唯一標(biāo)識(shí)符,用于確保在反序列化過(guò)程中類的實(shí)例與序列化文件中的類版本相匹配,它在版本兼容性和安全性方面起著關(guān)鍵作用2025-01-01Java Mail郵件發(fā)送如何實(shí)現(xiàn)簡(jiǎn)單封裝
這篇文章主要介紹了Java Mail郵件發(fā)送如何實(shí)現(xiàn)簡(jiǎn)單封裝,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11SpringBoot如何使用過(guò)濾器進(jìn)行XSS防御
想對(duì)全局的請(qǐng)求都進(jìn)行XSS防御可以使用servlet中的過(guò)濾器或者spring mvc中的攔截器,下面我們就來(lái)看看如何使用servlet中的過(guò)濾器進(jìn)行XSS防御吧2024-11-11