封装自定义异常

Posted wenwblog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了封装自定义异常相关的知识,希望对你有一定的参考价值。

  • 才开通博客没几天,不知道写什么东西,就把最近在项目中做的东西分享一下,开通博客也可以监督一下自己,技术的路很遥远,希望能通过写博客来让自己走的更远。

  • 一般在web项目中都需要定义一个全局异常来处理一些业务方面的异常,下面是自定义异常的一些代码。

1.自定义一个异常,然后继承RuntimeException

/**
 * @author zhuwenwen
 * @date 2018/8/16 20:18
 */
@Getter
public class CustomException extends RuntimeException {
    /**
     * 异常编码
     */
    private Integer code;

    /**
     * 附加数据
     */
    private Object data;

    public CustomException(String errorMsg) {

        super(errorMsg);
        this.code= CustomEnum.ERROR.getCode();
    }

    public CustomException(String errorMsg, Integer code) {
        super(errorMsg);
        this.code = code;
    }

    public CustomException(Integer code, String errorMsg, Throwable errorCourse) {
        super(errorMsg,errorCourse);
        this.code = code;
    }

    public CustomException(String message, Integer code, Object data) {
        super(message);
        this.code = code;
        this.data = data;
    }

}

2.定义一个全局异常处理的类

/**
 * 处理全局异常
 *
 * @author zhuwenwen
 * @date 2018/8/17 9:31
 */
@RestControllerAdvice
public class CustomExceptionHandler extends ResponseEntityExceptionHandler implements CustomExceptionHanlerTrit {


    private Logger logger=LoggerFactory.getLogger(CustomExceptionHandler.class);
    /**
     *
     * @see ResponseEntityExceptionHandler#handleExceptionInternal
     */
    @Override
    protected ResponseEntity<Object> handleExceptionInternal(Exception ex, Object body, HttpHeaders headers, HttpStatus status,WebRequest webRequest) {
        logger.warn("{}", ex.getMessage());

        return handleException(CustomEnum.FAILURE_HTTP.getCode() + status.value(), ex.getMessage(), null);
    }

    /**
     * 处理ServletException
     *
     * @param ex      异常
     * @return        异常处理结果
     */
    @ExceptionHandler(value = {ServletException.class})
    protected final ResponseEntity<Object> handleServletException(ServletException ex) {
        logger.error("{}", ex);

        return handleException(CustomEnum.FAILURE_SERVLET.getCode(), ex.getMessage(), null);
    }

    /**
     * 处理SQLException
     *
     * @param ex      异常
     * @return        异常处理结果
     */
    @ExceptionHandler(value = {SQLException.class})
    protected final ResponseEntity<Object> handleSQLException(SQLException ex) {
        logger.error("{}", ex);

        return handleException(CustomEnum.FAILURE_DB.getCode(), ex.getMessage(), null);
    }

    /**
     * 处理ConstraintViolationException
     *
     * @param ex      异常
     * @return        异常处理结果
     */
    @ExceptionHandler(value = {ConstraintViolationException.class})
    protected final ResponseEntity<Object> handleConstraintViolationException(ConstraintViolationException ex) {
        logger.error("{}", ex);

        String message = ex.getMessage();
        if (ex.getConstraintViolations() != null && !ex.getConstraintViolations().isEmpty()) {
            message = ex.getConstraintViolations().stream().findFirst().isPresent()
                    ? ex.getConstraintViolations().stream().findFirst().get().getMessage() : null;
        }

        return handleException(CustomEnum.FAILURE_VALIDATION.getCode(), message, null);
    }

    /**
     * 处理MorphedException
     *
     * @param ex      异常
     * @return        异常处理结果
     */
    @ExceptionHandler(value = {CustomException.class})
    protected final ResponseEntity<Object> handleMorphedException(CustomException ex) {
        logger.info("{}", ex);

        return handleException(ex.getCode(), ex.getMessage(),ex.getData());
    }

    /**
     * 处理RuntimeException
     *
     * @param ex      异常
     * @return        异常处理结果
     */
    @ExceptionHandler(value = {RuntimeException.class})
    protected final ResponseEntity<Object> handleRuntimeException(RuntimeException ex) {
        logger.error("{}", ex);

        return handleException(CustomEnum.FAILURE_UNKNOWN.getCode(), ex.getMessage(), null);
    }

}

3.封装成一个组件,可以打成jar包,供多个项目使用,那么可以自定义一个注解,然后在启动类上加上这个注解,即可使用。下面是一个简单的demo

/**
 * @author zhuwenwen
 * @date 2018/8/17 11:02
 */

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(CustomExceptionHandler.class)
@Documented
public @interface EnableCustomException {
    /**
     * 是否开启
     * @return
     */
    boolean enabled() default true;


}
/**
 * @author zhuwenwen
 * @date 2018/8/17 14:47
 */
public class CustomImportBeanDefination implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
        //是否含有@EnableMorphedException注解
        if (annotationMetadata.isAnnotated(EnableCustomException.class.getName())){
            //获取该注解上面的所有属性,然后封装成一个map
            MultiValueMap<String, Object> attributes = annotationMetadata.getAllAnnotationAttributes(EnableCustomException.class.getName());
            if(attributes.get(EnableCustomExceptionCode.ENABLED).equals(Boolean.TRUE)){
                BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.rootBeanDefinition(CustomExceptionHandler.class);
                beanDefinitionRegistry.registerBeanDefinition(CustomExceptionHandler.class.getName(),beanDefinitionBuilder.getBeanDefinition());
            }
        }
    }
}

以上是关于封装自定义异常的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段14——Vue的axios网络请求封装

Java异常封装(自定义错误码和描写叙述,附源代码)

封装自定义异常

自定义封装Exception异常抛出

drf自定义异常与封装response对象

SpringCloud请求异常处理封装BusinessException自定义异常类