通常一个web框架中,有大量需要处理的异常。比如业务异常,权限不足等等。前端通过弹出提示信息的方式告诉用户出了什么错误。 通常情况下我们用try…..catch….对异常进行捕捉处理,但是在实际项目中对业务模块进行异常捕捉,会造成代码重复和繁杂, 我们希望代码中只有业务相关的操作,所有的异常我们单独设立一个类来处理它。全局异常就是对框架所有异常进行统一管理。 我们在可能发生异常的方法里throw抛给控制器。然后由全局异常处理器对异常进行统一处理。 如此,我们的Controller中的方法就可以很简洁了。所谓全局异常处理器就是使用@RestControllerAdvice注解。
1、基于@RestControllerAdvice注解的Controller层的全局异常统一处理
/**
* 异常处理拦截器
*/
@RestControllerAdvice
public class GlobalExceptionHandler {
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler(BusinessException.class)
public HttpResult<?> handleRRException(BusinessException e){
log.error(e.getMessage(), e);
return HttpResult.error(e.getCode(),e.getMessage());
}
@ExceptionHandler(SystemException.class)
public HttpResult<?> handleRRException(SystemException e){
log.error(e.getMessage(), e);
return HttpResult.error(e.getCode(),e.getMessage());
}
@ExceptionHandler({UnauthorizedException.class, AuthorizationException.class})
public HttpResult<?> handleAuthorizationException(AuthorizationException e){
log.error(e.getMessage(), e);
return HttpResult.error(I18nUtil.message("system.unauthorized"));
}
…… //其它异常拦截,此次省略
}
2、Controller模块代码正常编写,无需单独处理异常。比如职务管理模块:
@RestController
@RequestMapping("/system/sysPosition")
public class SysPositionController extends BaseController<SysPosition, ISysPositionService> {
@Autowired
private ISysPositionService sysPositionService;
@PostMapping(value = "/add")
@AutoLog(value = "职务管理-添加")
public HttpResult<?> add(@RequestBody SysPosition sysPosition) {
sysPositionService.save(sysPosition);
return HttpResult.ok(I18nUtil.message("save.success"));
}
@PutMapping(value = "/edit")
@AutoLog(value = "职务管理-编辑")
public HttpResult<?> edit(@RequestBody SysPosition sysPosition) {
sysPositionService.updateById(sysPosition);
return HttpResult.ok(I18nUtil.message("update.success"));
}
@DeleteMapping(value = "/delete")
@AutoLog(value = "职务管理-删除")
public HttpResult<?> delete(@RequestParam(name="id",required=true) String id) {
sysPositionService.removeById(id);
return HttpResult.ok(I18nUtil.message("delete.success"));
}
}
3、业务中特殊逻辑,需要抛出异常的,可以直接throw new SystemException,可以用在Service层或Controller层,其中SystemException是平台定义的全局异常类。
public void checkUser (SysUser sysUser) throws Exception {
//情况1:根据用户信息查询,该用户不存在
if (sysUser == null) {
throw new SystemException(I18nUtil.message("user.not.exists"));
}
//情况2:根据用户信息查询,该用户已冻结
if (CommonConstant.USER_FREEZE.equals(sysUser.getStatus())) {
throw new SystemException(I18nUtil.message("user.blocked"));
}
}