【SpringBoot3】SpringBoot中实现全局统一异常处理

news/2023/6/9 19:09:53

在服务器端出现异常,或者客户端请求出错时,直接返回异常信息对用户来说是非常不友好的,我们需要对异常信息进行统一处理

1、使用 @ControllerAdvice 注解

使用 @ControllerAdvice 注解的控制层的全局统一异常处理

@ControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(Exception.class)public ModelAndView customException(Exception e) {ModelAndView mav = new ModelAndView();// 跳转到错误页面mav.setViewName("error");return mav;}
}

@ControllerAdvice 表示这是一个控制器增强类,当控制器发生异常且符合类中定义的拦截异常类,将会被拦截

@ExceptionHandler 则是定义拦截的异常类,可以是自定义异常类,例如:

@ExceptionHandler(value = MyException.class)
@ResponseBody
public JSONObject myErrorHandler(MyException exception) {JSONObject res = new JSONObject();res.put("code", exception.getCode());res.put("msg", exception.getMsg());return res;
}

当然,我们可以不返回页面,只返回异常信息

使用 @ControllerAdvice 只能捕获 Controller 层的异常,前提是 Controller 层没有对异常做 catch 处理

2、实现 ErrorController 接口

@Controller
@RequestMapping(value = "error")
@EnableConfigurationProperties({ServerProperties.class})
public class ExceptionController implements ErrorController {private ErrorAttributes errorAttributes;@Autowiredprivate ServerProperties serverProperties;/*** 初始化ExceptionController** @param errorAttributes*/@Autowiredpublic 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数据** @param request* @return*/@RequestMapping(value = "404")@ResponseBodypublic 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的错误JSON信息** @param request* @return*/@RequestMapping(value = "500")@ResponseBodypublic 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);}/*** 确定是否应包含stacktrace属性** @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;}/*** 获取错误的信息** @param request* @param includeStackTrace* @return*/private Map<String, Object> getErrorAttributes(HttpServletRequest request, boolean includeStackTrace) {RequestAttributes requestAttributes = new ServletRequestAttributes(request);return this.errorAttributes.getErrorAttributes((WebRequest) 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());}/*** 获取错误编码** @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;}}/*** 实现错误路径** @return*/@Overridepublic String getErrorPath() {return "";}}

总结
1、@ControllerAdvice 定义多个拦截方法,拦截不同的异常类,并且可以获取抛出的异常信息
2、@ControllerAdvice 只能捕获进入 Controller 层的异常,比如404,401等错误无法捕获
3、ErrorController,该方式几乎可以处理所有的异常,包括未进入控制器的错误,比如404,401等错误

当然,前提是没有对异常做 catch 处理才能捕获到
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.exyb.cn/news/show-4570423.html

如若内容造成侵权/违法违规/事实不符,请联系郑州代理记账网进行投诉反馈,一经查实,立即删除!

相关文章

【计算机图形学】 圆的两种生成算法(角度微分法、Bresenham算法)

圆的两种生成算法&#xff08;角度微分法、Bresenham算法&#xff09; 文章目录1.角度微分法的原理2.角度微分法的实现&#xff08;基于matlab&#xff09;3.Bresenham 算法的原理4.Bresenham 算法的实现&#xff08;基于matlab&#xff09;1.角度微分法的原理 圆的角度微分法…

JDK 8新特性之基本发展史

目录 一&#xff1a;Java SE的发展历史 二&#xff1a;Open JDK来源 三&#xff1a;Open JDK 和 Oracle JDK的关系 四&#xff1a;Open JDK 官网介绍 小结 &#xff1a; 一&#xff1a;Java SE的发展历史 Sun公司在1991年成立了一个称为绿色计划( Green Project )的项目&a…

【人物志】美团前端通道主席洪磊:一位产品出身、爱焊电路板的工程师

洪磊&#xff0c;2013年加入美团&#xff0c;目前是美团外卖事业部终端组的负责人&#xff0c;也是美团技术委员会前端通道主席。在加入美团之前&#xff0c;洪磊的职业生涯可以用“跌宕起伏”来形容。他就读于中南财经政法大学&#xff0c;曾任职于雅虎中国&#xff0c;先后担…

校招回忆录---骆驼篇

2015届[2014年秋]去哪儿网(开发工程师-安全)校招求职经历 本文由CSDN-蚍蜉撼青松【主页&#xff1a;http://blog.csdn.net/howeverpf】原创&#xff0c;转载请注明出处&#xff01; 需要提前说明的一点是&#xff0c;由于这系列文章都是记录我自身参加各大公司校招的经历&…

NatureArt:模拟自然现象的滤镜

AKVIS NatureArt 是一款强大的 Ps 滤镜插件&#xff0c;它可以为你的图像添加各种各样的自然效果。AKVIS NatureArt 可以独立运行&#xff0c;也可以做为 Ps 的滤镜使用&#xff0c;只需要动动手指便可以在照片中添加太阳、雨、雪、冰霜、彩虹、极光等各种特效了。官网地址http…

Godaddy

Godaddy是世界第一大域名注册商&#xff0c;进军主机领域以后发展迅速&#xff0c;据多家监测机构显示&#xff0c;放置在Godaddy上的网站数量已经越居第一位。Godaddy同时提供linux主机&#xff0c;Windows主机&#xff0c;VPS以及独立主机全线主机产品&#xff0c;各种需求的…

家人们接受DAO,拥抱DAO,DeFI崛起?

前有超过 2 亿美元被锁定在 DeFi 协议中&#xff0c;这表明鉴于 DeFi 相对近期的崛起&#xff0c;市场潜力巨大。监管机构正在关注并打击提供 DeFi 服务的中心化平台。BlockFi 最近与美国证券交易委员会达成了 1 亿美元的和解协议&#xff0c;并同意注册其加密借贷产品&#xf…

合规化潮流背后,DAO正走向现实世界

撰文&#xff1a;Richard Lee&#xff0c;链捕手“2022年是DAO爆发的元年。” 这是2021年终盘点时&#xff0c;各路预测集体看好的趋势之一。近期&#xff0c;Gitcoin、SuishiSwap等多个知名项目都宣布已经或计划为社区DAO设立法律实体&#xff0c;长期处于法律灰色地带的DAO呈…