JAVA Web 统一封装响应体[@ControllerAdvice]

JAVA Web通过ResponseBodyAdvice 拦截Controller统一封装响应体

  1. 封装返回数据
@ControllerAdvice
public class GlobalResponseBodyAdviceHandle implements ResponseBodyAdvice<Object> {

    /**
     * 是否对指定接口生效
     *  标注了RestController的接口有效
     * @param returnType  返回类型
     * @param converterType 转化类型
     * @return boolean
     */
    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        RestController restControllerClass = returnType.getDeclaringClass().getAnnotation(RestController.class);
        return restControllerClass != null;
    }

    /**
     * 怎样封装结果集
     *  [在supports指定的接口返回前调用]
     *
     * @param body 返回值
     * @param returnType    控制器方法的返回类型
     * @param selectedContentType 内容类型
     * @param selectedConverterType 转换器类型
     * @param request   当前请求
     * @param response  当前响应
     * @return  传入的主体或修改的(可能是新的)实例
     */
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType,
                                  MediaType selectedContentType,
                                  Class<? extends HttpMessageConverter<?>> selectedConverterType,
                                  ServerHttpRequest request, ServerHttpResponse response) {
        response.getHeaders().setContentType(MediaType.parseMediaType(MediaType.APPLICATION_JSON_UTF8_VALUE));

        Logger log = LoggerFactory.getLogger(returnType.getDeclaringClass());

        // 通过反射获取返回值全类名
        String bodyclassname = body == null ? null : body.getClass().getName();

        RestResult restResult = RestResult.success();
        // 一个对象是否为一个类的实例
        if (body instanceof RestResult) {
            restResult = (RestResult) body;
        }else if (body != null && bodyclassname.startsWith("com.baomidou.mybatisplus")) {
            // 判断是否是MyBatisPlus分页对象,是则使用反射获取Page对象属性值封装返回
            Class<?> bodyectClass = body.getClass();
            try {
                // 设置数据
                restResult.data(bodyectClass.getMethod("getRecords").invoke(body));

                JSONObject pageJson = new JSONObject();
                // 当前页,兼容之前版本使用pageNum的习惯
                pageJson.put("pageNum", bodyectClass.getMethod("getCurrent").invoke(body));
                pageJson.put("pageNo", bodyectClass.getMethod("getCurrent").invoke(body));
                // 每页的数量
                pageJson.put("pageSize", bodyectClass.getMethod("getSize").invoke(body));
                // 总条数
                pageJson.put("total", bodyectClass.getMethod("getTotal").invoke(body));
                // 总页数
                pageJson.put("pages", bodyectClass.getMethod("getPages").invoke(body));
                // 是否有上一页
                pageJson.put("hasPrevious", bodyectClass.getMethod("hasPrevious").invoke(body));
                // 是否有下一页
                pageJson.put("hasNext", bodyectClass.getMethod("hasNext").invoke(body));

                // 设置分页对象数据至page节点
                restResult.page(pageJson);
            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                throw new RuntimeException("封装Page对象返回值出错", e);
            }
        } else {
            if (body != null) {
                restResult.data(body);
            }
        }
        log.debug("response : {}", restResult.toJSONString());
        return restResult;
    }
}
  1. 封装返回对象
public class RestResult extends HashMap<String,Object> {

    @Override
    public RestResult put(String key, Object value) {
        super.put(key, value);
        return this;
    }

    @Override
    public String toString() {
        return this.toJSONString();
    }

    public RestResult(){
        put("code", ResponseCode.SUCCESS);
    }

    public static RestResult success(){
        return new RestResult();
    }

    public static RestResult success(String msg, Object... params) {
        RestResult error = new RestResult();
        error.put("msg", RestResult.formatMsg(msg, params));
        return error;
    }

    public static RestResult error(int code, String msg, Object... params) {
        RestResult e = new RestResult();
        e.put("code", code);
        e.put("msg", RestResult.formatMsg(msg, params));
        return e;
    }

    /**
     * 统一设置返回数据至page节点
     * @param data 返回数据
     * @return result
     */
    public RestResult data(Object data) {
        super.put("data", data);
        return this;
    }

    /**
     * 设置分页对象数据至page节点
     * @param page 分页对象
     * @return result
     */
    public RestResult page(Object page) {
        super.put("page", page);
        return this;
    }

    public String toJSONString() {
        return JSON.toJSONString(this);
    }

    /**
     * 格式化消息参数
     *
     * @param msg 消息体
     * @param params 参数
     * @return r
     */
    public static String formatMsg(String msg, Object... params) {
        int i = 0, j;
        StringBuilder content = new StringBuilder(msg.length() + 50);
        for (Object param : params) {
            j = msg.indexOf("{}", i);
            // 找到{}等待替换
            if (j != -1) {
                content.append(msg, i, j).append(param);
                i = j + 2;
            } else {
                break;
            }
        }
        content.append(msg, i, msg.length());
        return content.toString();
    }
}
  1. 返回码
public class ResponseCode {

    /**
     * 成功
     */
    public static final int SUCCESS = 200;

    /**
     * 系统错误
     */
    public static final int SYSTEM_EXCEPTION = 10500;

    /**
     * 结果集错误
     */
    public static final int RESULT_EXCEPTION = 10300;
    /**
     * 参数错误
     */
    public static final int PARAMETER_EXCEPTION = 10400;
    
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值