springboot 统一异常管理

工作时候使用到的异常统一处理,在此记录一下。按照步骤来,即可

如果直接把异常打印给前台,一个是前台看不懂,更主要没什么意义,还显得很low

第一步引入jar包

org.springframework.boot

spring-boot-starter-aop

二定义一个错误信息类

public class Result {

// error_code0 成功,其他 失败

private Integer status;

// error_msg 错误信息

private String msg;

// content 返回体报文的出参,使用泛型兼容不同的类型

private T data;

public Integer getStatus() {

return status;

}

public void setStatus(Integer code) {

this.status = code;

}

public String getMsg() {

return msg;

}

public void setMsg(String msg) {

this.msg = msg;

}

public T getData(Object object) {

return data;

}

public void setData(T data) {

this.data = data;

}

public T getData() {

return data;

}

@Override

public String toString() {

return "Result{" +

"status=" + status +

", msg='" + msg + '\'' +

", data=" + data +

'}';

}

第三步错误信息枚举

public enum ExceptionEnum {

UNKNOW_ERROR(-1,"未知错误"),

USER_NOT_FIND(-101,"用户不存在"),

;

private Integer code;

private String msg;

ExceptionEnum(Integer code, String msg) {

this.code = code;

this.msg = msg;

}

public Integer getCode() {

return code;

}

public String getMsg() {

return msg;

}

}

第四部返回信息工具类

public class ResultUtil {

/**

* 返回成功,传入返回体具体出參

* @param object

* @return

*/

public static Result success(Object object){

Result result = new Result();

result.setStatus(0);

result.setMsg("success");

result.setData(object);

return result;

}

/**

* 提供给部分不需要出參的接口

* @return

*/

public static Result success(){

return success(null);

}

/**

* 自定义错误信息

* @param code

* @param msg

* @return

*/

public static Result error(Integer code,String msg){

Result result = new Result();

result.setStatus(code);

result.setMsg(msg);

result.setData(null);

return result;

}

/**

* 返回异常信息,在已知的范围内

* @param exceptionEnum

* @return

*/

public static Result error(ExceptionEnum exceptionEnum){

Result result = new Result();

result.setStatus(exceptionEnum.getCode());

result.setMsg(exceptionEnum.getMsg());

result.setData(null);

return result;

}

}

第六步自定义异常

public class DescribeException extends RuntimeException{

private Integer code;

/**

* 继承exception,加入错误状态值

* @param exceptionEnum

*/

public DescribeException(ExceptionEnum exceptionEnum) {

super(exceptionEnum.getMsg());

this.code = exceptionEnum.getCode();

}

/**

* 自定义错误信息

* @param message

* @param code

*/

public DescribeException(String message, Integer code) {

super(message);

this.code = code;

}

public Integer getCode() {

return code;

}

public void setCode(Integer code) {

this.code = code;

}

}

第七步异常信息处理

@ControllerAdvice

public class ExceptionHandle {

private final static Logger LOGGER = LoggerFactory.getLogger(ExceptionHandle.class);

/**

* 判断错误是否是已定义的已知错误,不是则由未知错误代替,同时记录在log中

* @param e

* @return

*/

@ExceptionHandler(value = Exception.class)

@ResponseBody

public Result exceptionGet(Exception e){

if(e instanceof DescribeException){

DescribeException MyException = (DescribeException) e;

return ResultUtil.error(MyException.getCode(),MyException.getMessage());

}

LOGGER.error("【系统异常】{}",e);

return ResultUtil.error(ExceptionEnum.UNKNOW_ERROR);

}

}

我们使用了 @ControllerAdvice ,使Spring能加载该类,同时我们将所有捕获的异常统一返回结果Result这个实体。

第八部添加切面

@Aspect

@Component

public class HttpAspect {

private final static Logger LOGGER = LoggerFactory.getLogger(HttpAspect.class);

@Autowired

private ExceptionHandle exceptionHandle;

@Pointcut("execution(public * com.zzp.controller.*.*(..))")

public void log(){

}

@Before("log()")

public void doBefore(JoinPoint joinPoint){

ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

HttpServletRequest request = attributes.getRequest();

//url

LOGGER.info("url={}",request.getRequestURL());

//method

LOGGER.info("method={}",request.getMethod());

//ip

LOGGER.info("id={}",request.getRemoteAddr());

//class_method

LOGGER.info("class_method={}",joinPoint.getSignature().getDeclaringTypeName() + "," + joinPoint.getSignature().getName());

//args[]

LOGGER.info("args={}",joinPoint.getArgs());

}

@Around("log()")

public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

Result result = null;

try {

} catch (Exception e) {

return exceptionHandle.exceptionGet(e);

}

if(result == null){

return proceedingJoinPoint.proceed();

}else {

return result;

}

}

@AfterReturning(pointcut = "log()",returning = "object")//打印输出结果

public void doAfterReturing(Object object){

LOGGER.info("response={}",object.toString());

}

}

测试

@RestController

@RequestMapping("/result")

public class ResultController {

@Autowired

private ExceptionHandle exceptionHandle;

/**

* 返回体测试

* @param name

* @param pwd

* @return

*/

@RequestMapping(value = "/getResult",method = RequestMethod.POST)

public Result getResult(@RequestParam("name") String name, @RequestParam("pwd") String pwd){

Result result = ResultUtil.success();

try {

if (name.equals("zzp")){

result = ResultUtil.success(new UserInfo());

}else if (name.equals("pzz")){

result = ResultUtil.error(ExceptionEnum.USER_NOT_FIND);

}else{

int i = 1/0;

}

}catch (Exception e){

result = exceptionHandle.exceptionGet(e);

}

return result;

}

}


分享到:


相關文章: