自定义注解实现接口统一返回(携带注解才会统一返回)

问题:  发现每个接口请求返回的内容都不一样,前端处理起来麻烦;后端处理的话每个接口都要通过类似Result的对象返回

实现自定义注解: 优点:只要在接口类或者接口方法上携带该注解,接口都可以自动通过类似Result返回,不需要自己手动规整统一返回

展示:

 

步骤:

① 准备工作

  创建标识注解类 UnifiedReturn   (注解名字自定义)

import java.lang.annotation.*;

/**
 * @author hjh
 * 统一返回结果
 * Target是作用的范围
 */
@Target(value = {ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface UnifiedReturn {
}

创建统一返回结果类

import java.io.Serializable;

/**
 * @author root
 */
public class ResultData<T> implements Serializable {

    private static final long serialVersionUID = 2260434901667977303L;

    /**
     * code:状态码
     * msg:消息
     * exception:原始的异常信息,方便从页面排查问题.
     * total:分页时,表示所有页加起来的数据总数
     * pageNum:分页时,表示当前的页码
     * pageSize:分页时,表示每页显示的数据条数
     * pages:分页时,表示总页数
     */
    private int code;
    private String msg;
    private Long ts;

    private T data;

    public ResultData() {
    }

    public ResultData(ResultCode resultCode, T data) {
        this.code = resultCode.getCode();
        this.msg = resultCode.getMessage();
        this.data = data;
    }

    public ResultData(ResultCode resultCode, T data, String exception) {
        this.code = resultCode.getCode();
        this.msg = resultCode.getMessage();
        this.data = data;
    }

    public ResultData(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public Long getTs() {
        return System.currentTimeMillis();
    }

    public String getMessage() {
        return msg;
    }

    public void setMessage(String msg) {
        this.msg = msg;
    }

    public Object getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public static <T> ResultData<T> success() {
        return success(null);
    }

    public static <T> ResultData<T> success(T data) {
        return success(ResultCode.SUCCESS, data);
    }

    public static <T> ResultData<T> success(ResultCode resultCode, T data) {
        return success(resultCode, data, resultCode.getMessage());
    }

    public static <T> ResultData<T> success(ResultCode resultCode, T data, String msg) {
        ResultData<T> resultData = new ResultData<>(resultCode, data);
        resultData.setMessage(msg);
        return resultData;
    }
    public static <T> ResultData<T> error() {
        return error(ResultCode.FAIL);
    }

    public static <T> ResultData<T> error(String msg) {
        return error(ResultCode.FAIL, msg);
    }

    public static <T> ResultData<T> error(Integer code,String msg) {
        return new ResultData<>(code,msg);
    }

    public static <T> ResultData<T> error(ResultCode resultCode) {
        return error(resultCode, resultCode.getMessage());
    }

    public static <T> ResultData<T> error(ResultCode resultCode, String msg) {
        return error(resultCode, msg, null);
    }

    public static <T> ResultData<T> error(ResultCode resultCode, Exception e) {
        return error(resultCode, resultCode.getMessage(), e.toString());
    }

    public static <T> ResultData<T> error(ResultCode resultCode, String msg, String exception) {
        ResultData<T> resultData = new ResultData<>(resultCode, null, exception);
        resultData.setMessage(msg);
        return resultData;
    }

定义code编码 ResultCode

public enum ResultCode {

    SUCCESS(200, "操作成功"),
    SUCCESS_LOAD(200, "查询成功"),
    EXP_SUCCESS(200,"导出成功"),
    IMP_SUCCESS(200,"导入成功"),

    FAIL(500, "操作失败"),

    /**
     * 参数错误:1000-1999
     */
    PARAM_IS_FAIL(1000, "参数校验未通过"),

    PARAM_IS_INVALID(1001, "参数无效"),

    PARAM_IS_BLANK(1002, "参数为空"),

    PARAM_TYP_EBIND_ERROR(1003, "参数类型错误"),

    PARAM_NOT_C0MPLETE(1004, "参数缺失"),
    /**
     * 用户错误:2000-2999
     */
    USER_NOT_L0GGED_IN(2001, "用户未登录,访问的路径需要验证,请登录"),

    USER_L0GIN_ERROR(2002, "账号不存在或密码错误"),

    USER_ACCOUNT_F0_RBIDDEN(2003, "账号已被禁用"),

    USER_VERIFI_CODE_ERROR(2004, "验证码错误");

    private Integer code;
    private String message;

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

    public Integer getCode() {
        return this.code;
    }

    public String getMessage() {
        return this.message;
    }

② 创建UnifiedReturnAdvice,用于拦截处理

主要的目的是判断是否使用了@UnifiedReturn注解标注;定义返回的格式

其中的"com.tool.controller"为自己controller对应的包路径

import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * @author 
 */
@ControllerAdvice(basePackages = "com.tool.controller") // controller对应的包位置
public class UnifiedReturnAdvice implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {

        return returnType.getDeclaringClass().getName().contains("com.tool.controller");
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        Class<?> containingClass = returnType.getContainingClass();
        //判断进入的方法对应的接口上的注解,主要是判断当前接口对应的类上是否标注了我们定义的@UnifiedReturn注解,如果标注才统一返回
        boolean isContainUnifiedReturn = containingClass.isAnnotationPresent(UnifiedReturn.class);
//       判断的是进入的方法: returnType.hasMethodAnnotation(UnifiedReturn.class);
        if (!isContainUnifiedReturn) {
            return body;
        }
//必须对String类型进行单独处理,否则会报转换类型异常
        if (body instanceof String){
            return body;
        }
        return body instanceof ResultData ? body : ResultData.success(body);
    }

③ 在接口类上增加@UnifiedReturn注解,编写代码测试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

点份炸鸡778

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值