springboot项目使用advice做统一返回处理

ResponseBodyAdvice接口

public interface ResponseBodyAdvice<T> {

    // 是否支持advice功能
    // true 支持,false 不支持
    boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType);

    // 对返回数据进行处理
    @Nullable
    T beforeBodyWrite(@Nullable T body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response);
}

创建一个处理类实现ResponseBodyAdvice接口

记得添加@RestControllerAdvice注解

  • @RestControllerAdvice注解是@RestController注解的增强,可以实现三个方面的功能:
    • 全局异常处理
    • 全局数据绑定
    • 全局数据预处理
@RestControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice<Object> {

    @Resource
    private ObjectMapper objectMapper;

    @Override
    public boolean supports(@NonNull MethodParameter returnType, @NonNull Class<? extends HttpMessageConverter<?>> converterType) {
        // 判断是否要执行beforeBodyWrite方法,true为执行,false不执行
        return true;
    }
    
    // 对response处理的执行方法
    @SneakyThrows
    @Override
    public Object beforeBodyWrite(Object body, @NonNull MethodParameter returnType, @NonNull MediaType selectedContentType, @NonNull Class<? extends HttpMessageConverter<?>> selectedConverterType, @NonNull ServerHttpRequest request, @NonNull ServerHttpResponse response) {
        // String类型不能直接包装,所以要进行些特别的处理
        if (body instanceof String){
            // 将数据包装在BaseResult里后,再转换为json字符串响应给前端
            return objectMapper.writeValueAsString(ResultData.success(body));
        }
        // 已经封装则直接返回
        if (body instanceof ResultData){
            return body;
        }
        // 将原本的数据包装ResultData在里
        return ResultData.success(body);
    }
}

ResultData

@Data
public class ResultData<T> {
    private int status;
    private String message;
    private T data;
    private long timestamp;

    public ResultData(){
        this.timestamp = System.currentTimeMillis();
    }

    public static <T> ResultData<T> success(T data){
        ResultData<T> resultData = new ResultData<>();
        resultData.setStatus(ReturnCode.RC100.getCode());
        resultData.setMessage(ReturnCode.RC100.getMessage());
        resultData.setData(data);
        return resultData;
    }

    public static <T> ResultData<T> fail(int code, String message){
        ResultData<T> resultData = new ResultData<>();
        resultData.setStatus(code);
        resultData.setMessage(message);
        return resultData;
    }
}

ReturnCode

@Getter
public enum ReturnCode {
    RC100(100, "操作成功"),
    RC999(999, "操作失败"),
    RC200(200, "服务开启限流保护,请稍后再试!"),
    RC201(201, "服务开启降级保护,请稍后再试!"),
    RC202(202, "热点参数限流,请稍后再试!"),
    RC203(203, "系统规则不满足要求,请稍后再试!"),
    RC204(204, "系统规则不通过,请稍后再试!"),
    RC403(403, "无访问权限,请联系管理员授予权限"),
    RC401(401, "匿名用户访问无权限资源异常"),
    RC500(500, "系统错误,请稍后重试"),

    INVALID_TOKEN(2001, "访问令牌不合法"),
    ACCESS_DENIED(2003, "没有权限访问该资源"),
    CLIENT_AUTHENTICATION_FAILED(1001, "客户端认证失败"),
    USERNAME_OR_PASSWORD_ERROR(1002, "用户名或密码错误"),
    UNSUPPORTED_GRANT_TYPE(1003, "不支持的认证模式");

    private final int code;
    private final String message;
    ReturnCode(int code, String message){
        this.code = code;
        this.message = message;
    }
}

测试

@RestController
@RequestMapping("/product/attr")
public class ProductController {

    @Resource
    private ProductAttrService productAttrService;

    @GetMapping("/info/{attrId}")
    public ProductAttr getAttrIdById(@PathVariable("attrId") Long attrId){
        return productAttrService.getById(attrId);
    }

}

返回信息:

{
    "status": 100,
    "message": "操作成功",
    "data": {
        "attrId": 14,
        "attrName": "机身材质工艺",
        "searchType": 0,
        "valueType": 1,
        "icon": "xxx",
        "valueSelect": "以官网信息为准;陶瓷;玻璃",
        "attrType": 1,
        "enable": 1,
        "catelogId": 225,
        "showDesc": 0
    },
    "timestamp": 1711606818713
}
© 版权声明
THE END
喜欢就支持以下吧
点赞13 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容