Java封装统一的Result Model

在开发过程中,有时候会需要使用错误码+错误信息的形式,来返回某些业务操作的错误结果信息,来代替效率较低的异常传递。
这样就需要封装一个统一的Result model作为返回值,代替直接返回数据等结果。

1.定义错误码 - 错误信息接口

错误码可能是String、Integer、Long 等类型,也可能是enum类型。因此这里使用泛型来代替,错误码类型,可以提高灵活性
。也可以通过枚举直接实现CodeMessage接口。
public interface CodeMessage<C>{
    C getCode();
    String getMessage();
}

2.实现Result Model

这里定义的是service层的Result。有时候在controller层只会作一些简单的参数校验,在service层会作进一步的校验,
如果controller中需要统一返回一个JsonResult可以将ServiceResult作一个简单的转换器进行转换。
public class ServiceResult<T, C> implements Serializable {

    public static final CodeMessage<String> SUCCESS = new DefaultMessage<>("00000000", "success");

    private T data;
    private CodeMessage<C> message;
    private boolean isSuccess;

    ServiceResult(T data, boolean isSuccess, CodeMessage<C> message) {
        this.data = data;
        this.message = message;
        this.isSuccess = isSuccess;
    }

    public T getData() {
        return data;
    }

    public CodeMessage<C> getCodeMessage() {
        return message;
    }

    public boolean isSuccess() {
        return isSuccess;
    }

    public static <D, C> ServiceResultBuilder<D, C> success() {
        ServiceResultBuilder<D, C> builder = builder();
        return builder.isSuccess(true);
    }

    public static <D, C> ServiceResultBuilder<D, C> success(CodeMessage<C> codeMessage) {
        ServiceResultBuilder<D, C> builder = builder();
        return builder.isSuccess(true).code(codeMessage.getCode()).message(codeMessage.getMessage());
    }

    public static <D> ServiceResult<D, String> success(D data) {
        ServiceResultBuilder<D, String> success = success(SUCCESS);
        return success.data(data).build();
    }

    public static <D, C> ServiceResult<D, C> error(CodeMessage<C> codeMessage) {
        ServiceResultBuilder<D, C> builder = builder();
        return builder.isSuccess(false).code(codeMessage.getCode()).message(codeMessage.getMessage()).build();
    }

    public static <D, C> ServiceResultBuilder<D, C> error() {
        ServiceResultBuilder<D, C> builder = builder();
        return builder.isSuccess(false);
    }


    static <D, C> ServiceResultBuilder<D, C> builder() {
        return new ServiceResultBuilder<>();
    }

    public static class DefaultMessage<C> implements CodeMessage<C>, java.io.Serializable {

        private C code;
        private String message;

        public DefaultMessage(C code, String message) {
            this.code = code;
            this.message = message;
        }

        @Override
        public C getCode() {
            return code;
        }

        @Override
        public String getMessage() {
            return message;
        }

        @Override
        public String toString() {
            return "DefaultMessage{" +
                    "code=" + code +
                    ", message='" + message + '\'' +
                    '}';
        }
    }


    public static class ServiceResultBuilder<T, C> {

        private T data;
        private C code;
        private String message;
        private boolean isSuccess;

        ServiceResultBuilder() { //package private
        }

        public ServiceResultBuilder<T, C> data(T data) {
            this.data = data;
            return this;
        }

        ServiceResultBuilder<T, C> isSuccess(boolean isSuccess) {
            this.isSuccess = isSuccess;
            return this;
        }

        public ServiceResultBuilder<T, C> code(C code) {
            this.code = code;
            return this;
        }

        public ServiceResultBuilder<T, C> message(String message) {
            this.message = message;
            return this;
        }

        public ServiceResult<T, C> build() {
            Objects.requireNonNull(code, "code");
            Objects.requireNonNull(code, "message");
            return new ServiceResult<>(data, isSuccess, new DefaultMessage<>(code, message));
        }
    }

    @Override
    public String toString() {
        return "ServiceResult{" +
                "data=" + data +
                ", message=" + message +
                ", isSuccess=" + isSuccess +
                '}';
    }
}

3.使用

定义枚举错误码
pubilc enum CodeMessageEnum implements CodeMessage<Integer> {
   some_error(1001, "错误信息。");
   Integer code;
   String message;

   CodeMessageEnum(Integer code, String message) {
       this.code = code;
       this.message = message;
   }

   @Override
   public Integer getCode() {
       return code;
   }

   @Override
   public String getMessage() {
       return message;
   }
}
//返回正确结果带返回值。
ServiceResult<List<String>, String> s = ServiceResult.success(Arrays.asList("1", "2", "3"));
s.isSuccess(); //true
ServiceResult<?, Integer> e1 = ServiceResult.error(CodeMessageEnum.some_error);
e1.isSuccess(); //false
ServiceResult<?, Long> e2 = ServiceResult.error(new ServiceResult.DefaultMessage<>(1000L, "error"));
e2.isSuccess(); //false
//ServiceResult{data=[1, 2, 3], message=DefaultMessage{code=00000000, message='success'}, isSuccess=true}
System.out.println(s);
//ServiceResult{data=null, message=DefaultMessage{code=1001, message='错误信息。'}, isSuccess=false}
System.out.println(e1);
//ServiceResult{data=null, message=DefaultMessage{code=1000, message='error'}, isSuccess=false}
System.out.println(e2);

猜你喜欢

转载自blog.csdn.net/m0_38043362/article/details/79696296