在日常项目中写代码时经常会有需要返回错误信息的代码,如下:
public Result demo() {
Demo demo = demoRepository.getDemo();
if (demo != null) {
return new Result(CommonCode.SUCCESS, demo);
} else {
return new Result(CommonCode.FAIL, null);
}
}
上面的代码会有一些缺陷:
- 上边的代码只要操作不成功仅向用户返回统一的失败信息,无法区别具体的错误信息。
- 在方法中如果有异常该如何捕获,在项目中是service层还是controller层try/catch,无论在哪里进行异常捕获都会造成代码冗余,不易维护。
解决
- 在项目中判断校验失败时,直接抛出具体业务异常。
- 使用统一异常捕获类,向用户返回统一规范的响应信息。
解决步骤
- 编写统一异常类
这里继承RuntimeException没有继承Exception是因为java所有方法默认throw了RuntimeExceptin,这样在进行代码优化时不用重新throw
public class UnityException extends RuntimeException{
private Result result;
public UnityException(Result result) {
this.result = result;
}
public Result getResult(){
return this.result;
}
}
- 异常捕获类
这里的ControllerAdvice相当于controller的增强,ExceptionHandler注解在springmvc异常处理时被识别,然后执行。这样可以实现全局异常处理
@ControllerAdvice
public class ExceptionCatch {
private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionCatch.class);
/**
* 识别抛出异常,返回错误信息
* @param e
* @return
*/
@ExceptionHandler(UnityException.class)
@ResponseBody
public Result customException(UnityException e) {
LOGGER.error("catch exception : {}\r\nexception: ",e.getMessage(), e);
return = e.getResult();
}
/**
* 系统产生异常处理
* @param e
* @return
*/
@ExceptionHandler(Exception.class)
@ResponseBody
public Result customException(Exception e) {
LOGGER.error("catch exception : {}\r\nexception: ",e.getMessage(), e);
return new Result("服务器异常",null);
}
}
- 优化之前的代码
public Result demo() {
Demo demo = demoRepository.getDemo();
if (demo == null) {
throw new UnityException(自定义结果);
}
return new Result(CommonCode.SUCCESS, demo);
}
以上提供一种全局异常处理思路,代码上应该进行再次封装,比如结果类和抛出异常可以写成静态方法、还有result类也需要完善(代码部分看下就好,只是个Demo)。
当然全局异常处理也有其他的方式,比如springAOP等。