Springboot(十一)@ControllerAdvice全局异常处理 短命女 2022-05-22 12:22 239阅读 0赞 ##### 前言: ##### @ControllerAdvice,用于全局异常处理,减少代码入侵,必须在controller层抛出来,若异常在代码中被抓住了,没有抛出来,是不起作用的。 ##### 实现: ##### 写一个全局异常类GlobalDefaultException,类上加注解@RestControllerAdvice,在方法上加注解@ExceptionHandler(value = Exception.class) value表示要捕捉的异常,可以写多个,然后根据异常,就可以在这个方法里面进行处理。 ##### 代码: ##### 全局捕捉异常类:GlobalDefaultExceptionHandler.java package com.xhx.springboot.config; import com.xhx.springboot.exception.BusinessException; import com.xhx.springboot.result.JsonResult; import com.xhx.springboot.result.ReturnEnum; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; import javax.servlet.http.HttpServletRequest; import java.util.Objects; /** * xuhaixing * 2018/6/24 11:00 * 返回string或者json需要@ResponseBody * 用RestControllerAdvice,就不用加@ResponseBody了 **/ @RestControllerAdvice public class GlobalDefaultExceptionHandler { private static Logger logger = LoggerFactory.getLogger(GlobalDefaultExceptionHandler.class); @ExceptionHandler(value = Exception.class) public JsonResult<ReturnEnum> exceptionHandler(HttpServletRequest request, Exception e) { Throwable throwable = getBusinessException(e); if (!Objects.isNull(throwable)) { ReturnEnum returnEnum = ((BusinessException) throwable).getReturnEnum(); if(((BusinessException)throwable).getReturnEnum()!=null) { return JsonResult.error(returnEnum); } } return JsonResult.error(); } /** * 若有异常进行嵌套,打印出每个异常的堆栈信息,若包含自定义异常,返回最内部的BusinessException异常。 * @param e * @return */ private Throwable getBusinessException(Throwable e) { if (e == null) { return null; } else if (e instanceof BusinessException) { if(((BusinessException)e).getReturnEnum()!=null) { logger.info(((BusinessException) e).getReturnEnum().toString()); } e.printStackTrace(); Throwable temp = getBusinessException(e.getCause()); if (temp == null) { return e; } else { return temp; } } else { e.printStackTrace(); return getBusinessException(e.getCause()); } } } 自己封装的枚举类:ReturnEnum.java package com.xhx.springboot.result; /** * xuhaixing * 2018/6/24 11:41 **/ public enum ReturnEnum { success("200","",""), error("500","error","后台发生未知错误"); //自定义异常码 private String code; //国际化文件中的key private String type; //异常信息说明 private String message; ReturnEnum(String code, String type, String message){ this.code = code; this.type = type; this.message=message; } public String getCode() { return code; } public String getType() { return type; } public String getMessage() { return message; } @Override public String toString() { return "ReturnEnum{" + "code='" + code + '\'' + ", type='" + type + '\'' + ", message='" + message + '\'' + '}'; } } 自己封装的异常类,整合枚举类 package com.xhx.springboot.exception; import com.xhx.springboot.result.ReturnEnum; import javax.validation.constraints.NotNull; /** * xuhaixing * 2018/6/24 11:38 **/ public class BusinessException extends Exception { private ReturnEnum returnEnum; private Throwable cause; public BusinessException(ReturnEnum returnEnum) { super(returnEnum.getMessage()); this.returnEnum = returnEnum; } public BusinessException(ReturnEnum returnEnum, Throwable cause) { super(returnEnum.getMessage(), cause); this.returnEnum = returnEnum; this.cause = cause; } public BusinessException(Throwable cause) { super(cause); this.cause = cause; } public ReturnEnum getReturnEnum() { return returnEnum; } } 自己封装的统一返回前端的结果类 JsonResult.java: package com.xhx.springboot.result; import java.io.Serializable; /** * xuhaixing * 2018/6/24 14:02 **/ public class JsonResult<T> implements Serializable { private String code; private String message; private T data; public JsonResult(String code,String message,T data){ this.code=code; this.message = message; this.data = data; } public JsonResult(ReturnEnum returnEnum, T data){ this.code = returnEnum.getCode(); this.message = returnEnum.getMessage(); this.data = data; } public JsonResult(ReturnEnum returnEnum){ this.code = returnEnum.getCode(); this.message = returnEnum.getMessage(); } public static JsonResult success(){ return new JsonResult(ReturnEnum.success.getCode(),ReturnEnum.success.getMessage(),null); } public static <T> JsonResult success(T data){ return new JsonResult(ReturnEnum.success.getCode(),ReturnEnum.success.getMessage(),data); } public static JsonResult error(){ return new JsonResult(ReturnEnum.error.getCode(),ReturnEnum.error.getMessage(),null); } public static <T> JsonResult error(ReturnEnum returnEnum){ return new JsonResult(returnEnum.getCode(),returnEnum.getMessage(),null); } public String getCode() { return code; } public String getMessage() { return message; } public T getData() { return data; } } dao层: package com.xhx.springboot.dao; import com.xhx.springboot.entity.Account; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; /** * @author xuhaixing * @date 2018/5/2 11:19 */ @Repository public interface AccountDao extends JpaRepository<Account, Integer> { Account findByName(String name); } service层: package com.xhx.springboot.service; import com.xhx.springboot.dao.AccountDao; import com.xhx.springboot.entity.Account; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * @author xuhaixing * @date 2018/5/2 9:53 */ @Service public class AccountService { private static Logger logger = LoggerFactory.getLogger(AccountService.class); @Autowired private AccountDao accountDao; public Account findByName(String name) throws Exception{ try { return accountDao.findByName(name); } catch (Exception e) { throw new Exception("数据库异常",e); } } } controller层: package com.xhx.springboot.controller; import com.xhx.springboot.entity.Account; import com.xhx.springboot.exception.BusinessException; import com.xhx.springboot.result.JsonResult; import com.xhx.springboot.result.ReturnEnum; import com.xhx.springboot.service.AccountService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; /** * @author xuhaixing * @date 2018/5/2 9:55 */ @RestController @RequestMapping("account") public class AccountController { private static Logger logger = LoggerFactory.getLogger(AccountController.class); @Autowired private AccountService accountService; @RequestMapping(value = "findByName", method = RequestMethod.POST) public JsonResult<Account> findById(@RequestParam String name) throws Exception{ logger.info("name="+name); if(name == null || name.equals("")){ throw new BusinessException(ReturnEnum.error,new NullPointerException()); } Account account = null; try { account = accountService.findByName(name); } catch (Exception e) { throw new BusinessException(e); } return JsonResult.success(account); } } 实体类: package com.xhx.springboot.entity; import javax.persistence.Entity; import javax.persistence.Id; /** * @author xuhaixing * @date 2018/4/28 10:29 */ @Entity public class Account { @Id private int id; private String name; private Double money; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getMoney() { return money; } public void setMoney(Double money) { this.money = money; } } application.yml spring: datasource: username: xuhaixing password: xuhaixing url: jdbc:mysql://192.168.94.151:3306/mytest?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8 driver-class-name: com.mysql.jdbc.Driver jpa: hibernate: ddl-auto: update show-sql: true 启动类: package com.xhx.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Springboot24Application { public static void main(String[] args) { SpringApplication.run(Springboot24Application.class, args); } } 数据库中的值: ![70][] name是aaa的有两个,我有Account实体类接受的,一定会报错,bbb的有一个不会报错 ![70 1][] 先让jpa执行数据库赋值时报错,抛出Exception异常: ![70 2][] ![70 3][] 让入参name为空,抛出自定义BusinessException异常 ![70 4][] ![70 5][] 报错时返回的内容code为自己定义的异常码,message为自己定义的异常信息。异常信息还可以整合国际化,这样就更好了。我主要是讲@ControllerAdvice就不整合了,现在封装的就已经很复杂了。 [我的git代码地址][git] [70]: /images/20220522/3f941b943e1d4aba8ff8c160066d9fc5.png [70 1]: /images/20220522/9a46f97f26c1438a94c7c7bdd0d896d8.png [70 2]: /images/20220522/569ade90293c45cca4ce69ff9df0e924.png [70 3]: /images/20220522/68d9f0e872f24fbd89cc05cb756cd5cc.png [70 4]: /images/20220522/0c22b11ad16a41ac8ed3d51fceba7437.png [70 5]: /images/20220522/a43856d00d33416585e89276fb46e5a5.png [git]: https://github.com/xuhaixing/myDocument.git
相关 @ControllerAdvice全局处理异常 @ControllerAdvice,是Spring3.2提供的新注解,它是一个Controller增强器,可对controller中被 @RequestMapping注解的方法 短命女/ 2022年11月13日 00:50/ 0 赞/ 181 阅读
相关 十四、springboot全局处理异常(@ControllerAdvice + @ExceptionHandler) 十四、springboot全局处理异常(@ControllerAdvice + @ExceptionHandler) 参考文章: [(1)十四、springboot全局处理 深藏阁楼爱情的钟/ 2022年09月10日 04:21/ 0 赞/ 206 阅读
相关 Springboot(十一)@ControllerAdvice全局异常处理 前言: @ControllerAdvice,用于全局异常处理,减少代码入侵,必须在controller层抛出来,若异常在代码中被抓住了,没有抛出来,是不起作 短命女/ 2022年05月22日 12:22/ 0 赞/ 240 阅读
相关 @ControllerAdvice 全局异常处理 [ControllerAdvice 文档][ControllerAdvice] 在spring 3.2中,新增了@ControllerAdvice 注解,它通常用于定义 迈不过友情╰/ 2022年04月25日 01:36/ 0 赞/ 254 阅读
相关 @ControllerAdvice + @ExceptionHandler 全局处理 Controller 层异常 @ControllerAdvice public class ExceptionHandle { private static fin 朴灿烈づ我的快乐病毒、/ 2022年03月30日 08:00/ 0 赞/ 225 阅读
相关 springboot全局异常处理实例——@ControllerAdvice+ExceptionHandler 文章目录 一、全局捕获异常后,返回json给浏览器 1、自定义异常类 MyException.java 系统管理员/ 2022年03月15日 04:10/ 0 赞/ 299 阅读
相关 【java异常】 @ControllerAdvice+@ExceptionHandler全局异常处理 查看 @ControllerAdvice源码可见,添加了@Component; 则@ControllerAdvice是spring的一个组件,可理解为一个实体Bean, 叁歲伎倆/ 2021年12月05日 01:13/ 0 赞/ 326 阅读
相关 springboot全局异常处理 --- @ControllerAdvice 1、首先我们可以针对自己的业务创建自定义异常,系统层面,业务方面等 我们系统业务层统一使用BizException,这个是自定义的。 2、配置controllerAd 偏执的太偏执、/ 2021年11月22日 13:50/ 0 赞/ 391 阅读
相关 SpringBoot使用@ControllerAdvice和@ExceptionHandler注解实现全局异常处理 1、使用控制器通知 在编写代码时,需要对异常进行处理。进行异常处理的普通的代码是try...catch结构。但在开发业务时,只想关注业务正常的代码,对于catch语句中的 冷不防/ 2021年08月29日 12:47/ 0 赞/ 449 阅读
还没有评论,来说两句吧...