zoukankan      html  css  js  c++  java
  • 服务异常返回的设计

    服务异常返回的设计

    服务是不能抛出异常的(在《服务返回对象的设计》中有讨论这个问题)。

    为了实现这个目的,在Java实现中,我们通常会用try-catch-finally语句包含整个方法体。

    这样做是不优美的。

    优美的程序应该是简洁的只专注于做一件事(这里指不考虑异常处理),无重复代码的

    使用AOP处理服务方法抛出的异常

    解决上面问题的一种思路是:引入一个服务方法注解和一个服务异常处理Aspect。
    Aspect拦截服务方法,处理服务方法抛出的异常,并返回一个code为“ERROR”的服务返回对象。

    服务方法注解ServiceMethod

    @Target(ElementType.METHOD)  
    @Retention(RetentionPolicy.RUNTIME)   
    @Documented  
    public @interface ServiceMethod {}
    

    服务异常处理ServiceExcHandlerAspect

    需要依赖aspectjrt

    public class ServiceExcHandlerAspect {
        public Object doAroundMethod(ProceedingJoinPoint point) {
            Object response = null;
            try {
                response =  point.proceed();
            } catch (Throwable e) {
                ServiceResponse<Serializable> err = new ServiceResponse<Serializable>();
                err.setCode(ServiceCode.ERROR);
                response = err;
            }
            return response;
        }
    }
    

    Spring配置

    细粒度的异常码

    服务应该根据不同的服务,返回不同的异常码。
    如果一个服务方法在发生异常时,一概返回ERROR异常码,未免太粗暴。

    改进思路是引入服务异常类,这个异常类包含一个code字段。
    当Aspect处理这类异常时,会根据这个异常的code字段,创建服务返回对象。

    服务异常类

    public class ServiceException extends RuntimeException {
        private String code;
    
        public String getCode() {
            return code;
        }
    
        // 异常构造器
        ...
    }
    

    改进后的ServiceExcHandlerAspect

    public class ServiceExcHandlerAspect {
        public Object doAroundMethod(ProceedingJoinPoint point) {
            Object response = null;
            try {
                response =  point.proceed();
            } catch (ServiceException e) {
                response = exceptionResponse(e.getCode());
            } catch (Throwable e) {
                response = exceptionResponse(ServiceCode.ERROR);
            }
            return response;
        }
    
        private Object exceptionResponse(String code) {
            ServiceResponse<Serializable> err = new ServiceResponse<Serializable>();
            err.setCode(code);
            return err;
        }
    }
    

    另一种方案: 不使用AOP的传统方法

    如果你不喜欢使用AOP, 你可以

    public class ArticleListServiceImpl implements ArticleListService {
        ServiceResponse<ListArticleData> listArticle(ListArticleRequest request) {
            ServiceResponse<ListArticleData> response = null;
            try {
                response =  doListArticle(request);
            } catch (ServiceException e) {
                response = exceptionResponse(e.getCode());
            } catch (Throwable e) {
                response = exceptionResponse(ServiceCode.ERROR);
            }
                return response;
        }
    
        ServiceResponse<ListArticleData> doListArticle(ListArticleRequest request) {
                ...
        }
        ...
    }
  • 相关阅读:
    MongoDB pymongo模块 删除数据
    MongoDB pymongo模块 查询
    MongoDB pymongo模块 插入数据
    MongoDB pymongo模块 更新数据
    pymongo模块 目录
    POJ 1579
    POJ 1631
    POJ 1573
    POJ 1607
    POJ 1552
  • 原文地址:https://www.cnblogs.com/zyunx/p/7123476.html
Copyright © 2011-2022 走看看