java异常处理方式的升级

233 阅读1分钟

传统的异常处理方式

  try {

            //业务处理

            initResult(result, null, commodityDto);

        } catch (BusinessException e) {

            Log.error("处理异常:{}", ErrorUtils.getErrorMessage(e));

            return new Result<>(ServiceError.SERVICE_PROCESS_ERROR.value(), e.getMessage());

        }catch (Exception e) {

            Log.error("处理异常:{}", ErrorUtils.getErrorMessage(e));

            return new Result<>(ServiceError.SERVICE_PROCESS_ERROR.value(), e.getMessage());

        }

目前比较通用的处理方式:全局异常处理

针对不同的异常,进行统一的处理,

@RestControllerAdvice

public class GlobalExceptionHandler {

 

    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

 

    @ExceptionHandler(AuthorizationException.class)

    private ResponseEntity handleAuthorizationException(AuthorizationException e, HttpServletRequest request) {

        String requestURI = request.getRequestURI();

        log.error("请求地址'{}',权限校验失败'{}'", requestURI, e.getMessage());

        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());

    }

 

    @ExceptionHandler(Exception.class)

    private ResponseEntity handleException(Exception e, HttpServletRequest request) {

        String requestURI = request.getRequestURI();

        log.error("请求地址'{}',校验失败'{}'", requestURI, e.getMessage());

        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());

    }

}

当然此种方式只适用于SpringMVC中Controller/RestController使用

实现原理: 注解+切面

实现方式

1、定义切面配置

@Configuration

public class ExceptionConfig {

    @Bean

    public AspectJExpressionPointcutAdvisor configurabledvisor()

    {

        AspectJExpressionPointcutAdvisor advisor = new AspectJExpressionPointcutAdvisor();

        advisor.setExpression("execution(com.jun.service...(..)) && @annotation(com.ztocwst.stone.common.annotation.Annotation)");

        advisor.setAdvice(new ExceptionHandler());

        return advisor;

    }

}

2、定义异常处理拦截

@Component public class ExceptionHandler implements MethodInterceptor {

    @Override

    public Object invoke(MethodInvocation methodInvocation)

            throws Throwable

    {

        return handler(methodInvocation);

    }

    public Object handler(MethodInvocation methodInvocation) throws Throwable {

        Annotation annotation = (Annotation)methodInvocation.getMethod().getAnnotation(Annotation.class);

        String url = annotation == null ? "" : annotation.value();

        try {

            return methodInvocation.proceed();

        } catch (Exception e) {

            Log.error("url:{},系统异常:{}", url, ErrorUtils.getErrorMessage(e));

            return handleException(e);

        }

    }

    public Result handleException(Exception e)

    {

        return new Result(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage());

    }

}

3、使用 @Override

    @Annotation(name = "查询用户", value = "zl.base.getUser")

    public Result getUser(Long userId){

        Result result = new Result<>();

        if(userId.getId()==null){

            throw new BusinessException(UserServiceError.SERVICE_CHECK_PARAM_NULL);

        }

        //具体查询

    }