范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

SpringBoot统一处理全局异常

  注解的介绍
  @ControllerAdvice
  @ControllerAdvice注解是Spring3.2中新增的注解,学名是Controller增强器,作用是给Controller控制器添加统一的操作或处理。
  这里ControllerAdvice也可以这么理解,其抽象级别应该是用于对Controller进行切面环绕的,而具体的业务织入方式则是通过结合其他的注解来实现的。@ControllerAdvice是在类上声明的注解,其用法主要有三点:1.结合方法型注解@ExceptionHandler,用于捕获Controller中抛出的指定类型的异常,从而达到不同类型的异常区别处理的目的。
  2.结合方法型注解@InitBinder,用于request中自定义参数解析方式进行注册,从而达到自定义指定格式参数的目的。
  3.结合方法型注解@ModelAttribute,表示其注解的方法将会在目标Controller方法执行之前执行。
  从上面的讲解可以看出,@ControllerAdvice的用法基本是将其声明在某个bean上,然后在该bean的方法上使用其他的注解来指定不同的织入逻辑。不过这里@ControllerAdvice并不是使用AOP的方式来织入业务逻辑的,而是Spring内置对其各个逻辑的织入方式进行了内置支持。针对声明@ExceptionHandler 、 @InitBinder或@ModelAttribute方法的类的@Component @ExceptionHandler , @InitBinder在多个@Controller类之间共享。
  使用@ControllerAdvice注解的类可以明确声明为 Spring bean 或通过类路径扫描自动检测。 所有此类 bean 都根据Ordered语义或@Order / @Priority声明进行Ordered , Ordered语义优先于@Order / @Priority声明。 然后在运行时按该顺序应用@ControllerAdvice bean。 但是请注意,实现PriorityOrdered @ControllerAdvice bean 的PriorityOrdered不高于实现Ordered @ControllerAdvice bean。 此外, Ordered不适用于范围内的@ControllerAdvice例如,如果这样的 bean 已被配置为请求范围或会话范围的 bean。 对于处理异常, @ExceptionHandler将在第一个具有匹配异常处理程序方法的通知中被选择。 对于模型的属性和数据绑定初始化, @ModelAttribute和@InitBinder方法将遵循@ControllerAdvice秩序。
  注意:对于@ExceptionHandler方法,在特定建议 bean 的处理程序方法中,根异常匹配将优先于仅匹配当前异常的原因。 但是,与较低优先级建议 bean 上的任何匹配(无论是根还是原因级别)相比,更高优先级建议上的原因匹配仍然是首选。 因此,请在具有相应顺序的优先建议 bean 上声明您的主要根异常映射。
  默认情况下, @ControllerAdvice ControllerAdvice 中的方法全局应用于所有控制器。 使用诸如annotations 、 basePackageClasses和basePackages (或其别名value )之类的选择器来定义目标控制器的更窄子集。 如果声明了多个选择器,则应用布尔OR逻辑,这意味着所选控制器应至少匹配一个选择器。 请注意,选择器检查是在运行时执行的,因此添加许多选择器可能会对性能产生负面影响并增加复杂性。
  @ExceptionHandler拦截异常并统一处理
  配合 @ExceptionHandler注解结合使用,当异常抛到controller层时,可以对异常进行统一的处理,规定返回的json格式或者跳转到指定的错误页面等.
  @ExceptionHandler的作用主要在于声明一个或多个类型的异常,当符合条件的Controller抛出这些异常之后将会对这些异常进行捕获,然后按照其标注的方法的逻辑进行处理,从而改变返回的视图信息。
  用于处理特定处理程序类和/或处理程序方法中的异常的注解。
  使用此注解注释的处理程序方法允许具有非常灵活的签名。 它们可能具有以下类型的参数,按任意顺序排列:
  异常参数:声明为一般异常或更具体的异常。 如果注解本身没有通过其value()缩小异常类型,这也可用作映射提示
  代码实现
  自定义异常/**  * 自定义一个异常类,用于处理我们发生的业务异常  *  * @author Promsing(张有博)  * @version 1.0.0  * @since 2021/11/27 - 20:14  */ public class BizException extends RuntimeException {       private static final long serialVersionUID = 1L;       /**      * 错误码      */     protected String errorCode;     /**      * 错误信息      */     protected String errorMsg;       public BizException() {         super();     }       public BizException(FrontResult errorInfoInterface) {         super(errorInfoInterface.getCode());         this.errorCode = errorInfoInterface.getMessage();         this.errorMsg = errorInfoInterface.getMessage();     }       public BizException(FrontResult errorInfoInterface, Throwable cause) {         super(errorInfoInterface.getCode(), cause);         this.errorCode = errorInfoInterface.getCode();         this.errorMsg = errorInfoInterface.getMessage();     }       public BizException(String errorMsg) {         super(errorMsg);         this.errorMsg = errorMsg;     }       public BizException(String errorCode, String errorMsg) {         super(errorCode);         this.errorCode = errorCode;         this.errorMsg = errorMsg;     }       public BizException(String errorCode, String errorMsg, Throwable cause) {         super(errorCode, cause);         this.errorCode = errorCode;         this.errorMsg = errorMsg;     }         public String getErrorCode() {         return errorCode;     }       public void setErrorCode(String errorCode) {         this.errorCode = errorCode;     }       public String getErrorMsg() {         return errorMsg;     }       public void setErrorMsg(String errorMsg) {         this.errorMsg = errorMsg;     }       public String getMessage() {         return errorMsg;     }       @Override     public Throwable fillInStackTrace() {         return this;     }   }
  统一异常处理
  import com.tfjy.arbackend.enumtool.ResultCodeEnum; import com.tfjy.arbackend.enumtool.ResutlMsgEnum; import com.tfjy.arbackend.util.FrontResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody;   import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; import java.sql.SQLException;   /**  * 统一异常处理  *  * @author Promsing(张有博)  * @version 1.0.0  * @since 2021/11/27 - 20:14  */ @ControllerAdvice//使用该注解表示开启了全局异常的捕获 public class GlobalExceptionHandler {     private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);       /**      * 处理自定义的业务异常      * @param req      * @param e      * @return      */     @ExceptionHandler(value = BizException.class)     @ResponseBody     public  FrontResult bizExceptionHandler(HttpServletRequest req, BizException e){         logger.error("URL : " + req.getRequestURL().toString());         logger.error("HTTP_METHOD : " + req.getMethod());         logger.error("发生业务异常!原因是:{}",e.getErrorMsg());         return FrontResult.getExceptionResult(e.getErrorCode(),e.getErrorMsg());     }       /**      * 处理空指针的异常      * @param req      * @param e      * @return      */     @ExceptionHandler(value =NullPointerException.class)     @ResponseBody     public FrontResult exceptionHandler(HttpServletRequest req, NullPointerException e)  {         logger.error("URL : " + req.getRequestURL().toString());         logger.error("HTTP_METHOD : " + req.getMethod());         logger.error("发生空指针异常!原因是:",e);         return FrontResult.getExceptionResult(ResultCodeEnum.FAIL.getCode(), ResutlMsgEnum.EXECUTE_FAIL.getMsg());     }       /**      * 处理索引越界异常      * @param req      * @param e      * @return      */     @ExceptionHandler(value =IndexOutOfBoundsException.class)     @ResponseBody     public FrontResult exceptionHandler(HttpServletRequest req, IndexOutOfBoundsException e){         logger.error("URL : " + req.getRequestURL().toString());         logger.error("HTTP_METHOD : " + req.getMethod());         logger.error("索引越界异常!原因是:",e);         return FrontResult.getExceptionResult(ResultCodeEnum.FAIL.getCode(), ResutlMsgEnum.EXECUTE_FAIL.getMsg());     }       /**      * 处理类未找到异常      * @param req      * @param e      * @return      */     @ExceptionHandler(value =ClassNotFoundException.class)     @ResponseBody     public FrontResult exceptionHandler(HttpServletRequest req, ClassNotFoundException e)  {         logger.error("URL : " + req.getRequestURL().toString());         logger.error("HTTP_METHOD : " + req.getMethod());         logger.error("发生类未找到异常!原因是:",e);         return FrontResult.getExceptionResult(ResultCodeEnum.FAIL.getCode(), ResutlMsgEnum.EXECUTE_FAIL.getMsg());     }         /**      * 处理SQL异常      * @param req      * @param e      * @return      */     @ExceptionHandler(value = SQLException.class)     @ResponseBody     public FrontResult exceptionHandler(HttpServletRequest req, SQLException e)  {         logger.error("URL : " + req.getRequestURL().toString());         logger.error("HTTP_METHOD : " + req.getMethod());         logger.error("发生SQL异常!原因是:",e);         return FrontResult.getExceptionResult(ResultCodeEnum.FAIL.getCode(), ResutlMsgEnum.EXECUTE_FAIL.getMsg());     }       /**      * 处理IO异常      * @param req      * @param e      * @return      */     @ExceptionHandler(value = IOException.class)     @ResponseBody     public FrontResult exceptionHandler(HttpServletRequest req, IOException e)  {         logger.error("URL : " + req.getRequestURL().toString());         logger.error("HTTP_METHOD : " + req.getMethod());         logger.error("发生IO异常!原因是:",e);         return FrontResult.getExceptionResult(ResultCodeEnum.FAIL.getCode(), ResutlMsgEnum.EXECUTE_FAIL.getMsg());     }         /**      * 处理其他异常      * @param req      * @param e      * @return      */     @ExceptionHandler(value =Exception.class)     @ResponseBody     public FrontResult exceptionHandler(HttpServletRequest req, Exception e){         logger.error("URL : " + req.getRequestURL().toString());         logger.error("HTTP_METHOD : " + req.getMethod());         logger.error("未知异常!原因是:",e);         return FrontResult.getExceptionResult(ResultCodeEnum.FAIL.getCode(), ResutlMsgEnum.EXECUTE_FAIL.getMsg());     }       }
  前端返回值类
  import com.tfjy.arbackend.enumtool.ResultCodeEnum; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;   @Data @AllArgsConstructor @NoArgsConstructor public class FrontResult {     /**      * 结果状态码      */     private String code;     /**      * 响应结果描述      */     private String message;     /**      * 返回数据      */     private Object data;       /**      * 静态方法,返回前端实体结果      *      * @param code    状态码      * @param message 消息      * @param data    数据      * @return 前端实体结果      */     public static FrontResult build(String code, String message, Object data) {         return new FrontResult(code, message, data);     }       /**      * 返回成功的结果实体      *      * @param message 消息      * @param data    数据      * @return 实体      */     public static FrontResult getSuccessResult(String message, Object data) {         FrontResult result = new FrontResult();         result.code = ResultCodeEnum.SUCCESS.getCode();         result.message = message;         result.data = data;         return result;     }       /**      * 返回无需data的成功结果实体      *      * @param message 消息内容      * @return 返回结果      */     public static FrontResult getSuccessResultOnlyMessage(String message) {         FrontResult result = new FrontResult();         result.code = ResultCodeEnum.SUCCESS.getCode();         result.message = message;         result.data = null;         return result;     }       /**      * 获取一个异常结果      *      * @param code 错误码      * @param message 自定义异常信息      * @return FrontResult      */     public static FrontResult getExceptionResult(String code, String message) {         FrontResult result = new FrontResult();         result.code = code.isEmpty() ? ResultCodeEnum.CODE_EXCEPTION.getCode() : code;         result.message = message.isEmpty() ? ResultCodeEnum.CODE_EXCEPTION.getMsg() : message;         return result;     } }import lombok.AllArgsConstructor;   @AllArgsConstructor public enum ResultCodeEnum {     // 请求成功     SUCCESS("0000"),     // 请求失败     FAIL("1111"),     // EXCEL 导入失败     EXCEL_FAIL("1000"),     // userID 为空     ID_NULL("1001"),     // 前端传的实体为空     MODEL_NULL("1002"),     // 更新失败     UPDATE_FAIL("1011"),     // 参数为空     PARAM_ERROR("400"),     // 代码内部异常     CODE_EXCEPTION("500", "代码内部异常");       /**      * 状态码      */     private String code;       public String getCode() {         return code;     }       ResultCodeEnum(String code) {         this.code = code;     }       private String msg;       public String getMsg() {         return msg;     }   }     public enum ResutlMsgEnum {       //查询成功     FIND_SUCCESS("查询成功!"),     //查询失败     FIND_FAIL("查询失败!"),       //更新成功     UPDATE_SUCCESS("更新成功"),     //更新失败     UPDATE_FAIL("更新成功"),         SEND_SUCCESS("发送成功"),       SEND_FAIL("发送失败");         private String msg;       ResutlMsgEnum(String msg) {         this.msg = msg;     }       public String getMsg() {         return msg;     } }
  测试用例/**  * 测试用例  *  * @author Promsing(张有博)  * @version 1.0.0  * @since 2021/11/29 - 9:05  */ @Api(tags = {"测试controller"}) @RequestMapping(value = "/testController") @RestController public class TestController {           @ApiOperation(value = "测试null")     @GetMapping(value = "getNull")     public FrontResult getNull() {         int length = 0;               String name=null;             length = name.length();             return FrontResult.build(ResultCodeEnum.SUCCESS.getCode(),                 ResutlMsgEnum.EXECUTE_SUCCESS.getMsg(), length);     } }
  其他异常同理,也可以捕获。完美,没问题。全局统一异常处理设置成功。

2020完美落幕,Balneaire范德安蝉联双12游泳销冠2020年各大品牌的线上收官之战天猫双12年终盛典已经完美落幕,被众多明星喜爱的时尚泳装品牌Balneaire范德安轻松蝉联双12游泳类目销冠,为2020年线上泳装市场画上了圆满的渠道助力销售新国货品牌SKG发布会当天新品上线2小时即售罄伴随各行业出现不同程度的生产过剩的情况,渠道选择在销售环节中的地位越来越突出,其对品牌资产的积累和最终销售结果起着决定性作用。针对该趋势,品牌需不断读懂用户健康需求,洞悉用户消费偏实拍长安欧尚X7PLUS,预售7。99万起,搭载全场景智能车机系统!对于年轻人来说,买车会注重性价比以及颜值,即将上市的长安欧尚X7PLUS近几个月来备受关注,在定位上依旧是紧凑型SUV。目前正式开启预售,预售价格在7。9913。59万,价格跨度看优秀传统文化双创需要创新话语体系我国是一个有着五千年璀璨历史的文明古国,有着丰富的优秀传统文化资源,但如何科学地传承和发展优秀传统文化却困难重重,尤其是有效地把接触难看不懂的博物馆文物活起来更是个大难题。党的十九决策参考罗辑思维备战科创板马云获福布斯终身成就奖1字节跳动K12教育硬件产品预计明年年初发布事件10月14日,据晚点Latepost报道,字节跳动清北网校项目负责人刘庸离职,教育业务迎来90后CEO。字节跳动方面表示,教育是字节我国传统媒体为什么会更惨?早在2008年,在新媒体与金融危机的双重冲击下,美国报业广告收入陷入断崖式下滑,同比下滑14。9,2009年更是同比下滑26。6,而我国报业2012年才出现断崖式下滑,但是经过近几决策参考我国网民规模破8亿网易博客将停止运营1CNNIC第42次调查报告网民规模破8亿事件近日,中国互联网络信息中心(CNNIC)在京发布第42次中国互联网络发展状况统计报告,下面是主要数据。(1)网民规模。截至2018年6摩托罗拉即将发布新机,8月亮相,主打中端市场摩托罗拉正式宣布将于8月5日在中国举行一场以亿起惊艳为主题的新闻发布会,此次发布会的主角将是全新的Edge20系列。近日也有网友发布了Edge20Pro的全景渲染图,展示了设计和一决策参考快手推出独立App追鸭我国网民规模达8。54亿1快手推出独立App追鸭事件今年4月,快手为平台上各类型竖屏短剧开辟了一个新的功能板块快手小剧场,内容创作者在发布竖屏短剧相关作品时带上快手小剧场标签或者快手小剧场,就有机会被收录如何选择英国的加密交易所?在选择加密交易所交易加密货币时,你应该注意平台可靠性交易工具的可用性和流动性等指标。某一交易所的交易量越大,流动性就越高,对市场健康的信心就越大。如果你正在寻找英国的加密交易所,想加密货币经纪公司eToro添加LINK和UNI交易eToro通过其交易平台向零售投资者提供的16种代币中增加了Chainlink(LINK)和UNIswap(UNI)。今天宣布的这一举动标志着eToro认可以太坊蓬勃发展的去中心化
找不到老祖不修谱?家谱究竟是为谁修?乱世藏金,盛世修谱已成俗例,谱书是除了是家族人口的统计之书,更是记录家族发展史实之本,彰显族人德行之地,明证家族成员道义之纲,家族文萃汇集之册。老家谱如今欣逢盛世,各个姓氏家族都在杨氏家训家规,激励后世子孙,感到骄傲和自豪家庭是社会的细胞,是培育和践行社会主义核心价值观的重要阵地,重视家庭建设注重家教家风传承优良家训,是每个家庭必须重视的事情。家风传承更是一个家族,不可懈怠的社会责任。杨氏家训杨氏作从此再无虚焦烦恼!华为nova7Pro眼部追焦技术让你回归清晰世界现如今,微信微博小红书等各大社交平台分享日常已成为我们生活方式之一,越来越多人已习惯通过自拍或视频来记录和分享生活的点点滴滴,尤其是年轻人,自拍分享已成为生活中不或缺的事情。但相信体操王子陈一冰做客荣耀618直播间,世界冠军见证荣耀品质昨晚,体操王子陈一冰来到荣耀618全民5G,中国荣耀的直播间,分享他的独家硬核健身术,不得不说,昨晚荣耀直播间真是流动着满满的荷尔蒙啊。作为2008年中国体操乃至整个中国体育最辉煌被主席钦点的破译员,邹家人的骄傲1937年春在延安城门邹毕兆(左)毛主席为了解放全中国,当年和蒋介石打仗的时候就说过,和蒋介石打仗,我们是玻璃杯里押宝,看得准,赢得了。这个玻璃杯就是破译敌人密码工作。简单的一句话出版社书店博物馆,世界读书日,我们一起趣阅读世界没有任何快艇像一本书,把我们带到遥远的地方也没有任何骏马,能像一页欢悦的诗篇,最贫穷的人也可在书里旅行。又是一年世界读书日到来之际,趣市集和湖南图书馆相约准备一场愉快的阅读聚会,邀中百多点Dmall努力满足武汉居民个性化生活需求2月26日上午,省委书记省新冠肺炎疫情防控指挥部指挥长应勇,省委常委市委书记王忠林等省市领导一行,到中百仓储黄浦路店调研检查市场供应工作,并看望慰问一线员工。中百集团总经理杨晓红就三星S7Active评测,军工三防的S7前言三星S7是三星2016年2月发布的一部旗舰手机,因为其漂亮的外观,顶级的硬件配置,还有防水以及可扩展内存的加持,销量一直非常的好(大部分是S7EDGE),然而三星其实每一代旗舰浅谈WindowsPhone为何失败自从iOS问世以来,智能移动终端的市场就打得不可开交,在此之前,一直都是塞班系统的天下,其他系统可以用忽略不计来形容。当看到手机端有这么大一片市场,作为PC系统老大的微软也想分一块开启猎杀时刻,海盗船KatarProW双模游戏鼠标分享说起美商海盗船,大家第一时间会想到K70K95旗舰级机械键盘,也会想到旗下的机箱电源和散热硬件等装备,然而作为外设大厂,虽然也出过不少鼠标,但给我留下比较深刻的印象,也就只剩下那只安桥单元和电竞耳机的奇妙结合,微星GH61游戏耳机分享板卡大厂MSI微星旗下的外设产品经过了三年多的市场磨砺,基本已经做到了全线布局,各个档位都有能独挡一面的产品,性能和品质也在以肉眼可见的速度进步,也顺应市场推出过一些主打性价比的产