SpringBoot中优雅统一回包格式

前言

之前有写过博客简单过了一下,如果修改回包格式的。现在又找到一种新的方法,并且这样的方式好像更加合理。所以特地记录一下。

需求

对回包格式经行统一的封装。比如:

public class Response {
    private int code;
    private String requestId;
    private T data;
}

而我们的业务,一般都是回复Modle对象,比如:

@RestController
public class HelloController {
    @PostMapping("/hello/{name}")
    public String hello(@PathVariable String name) {
        return "hello " + name;
    }
}

因此我们要将回包经行封装。

分析

主要用到两个接口:

  • ResponseBodyAdvice
  • RequestBodyAdvice

作用时机:

  • ResponseBodyAdvice应用于流被写出前
  • RequestBodyAdvice应用于参数被@RequestBody使用之前

实践

回包
@RestControllerAdvice
public class CommonResponse implements ResponseBodyAdvice<Object> {

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

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        if (!(body instanceof Response)) {
            try {
                Object requestId = RequestContextHolder.currentRequestAttributes().getAttribute("requestId", RequestAttributes.SCOPE_REQUEST);
                Response<?> commonResponse = new Response<>(body);
                if (requestId != null) {
                    commonResponse.setRequestId(requestId.toString());
                }
                return new ObjectMapper().writeValueAsString(commonResponse);
            } catch (JsonProcessingException e) {
                return body;
            }
        }
        return body;
    }
}
请求包
@RestControllerAdvice
public class CommonRequest implements RequestBodyAdvice {

    @Override
    public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        return true;
    }

    @Override
    public HttpInputMessage beforeBodyRead(HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) throws IOException {
        int available = httpInputMessage.getBody().available();
        byte[] bytes = new byte[available];
        int read = httpInputMessage.getBody().read(bytes);
        if (read <= 0) {
            return httpInputMessage;
        }

        JsonNode jsonNode = new ObjectMapper().readValue(bytes, JsonNode.class);
        if (!jsonNode.hasNonNull("requestId")) {
            RequestContextHolder.currentRequestAttributes().setAttribute("requestId", UUID.randomUUID().toString(), RequestAttributes.SCOPE_REQUEST);
        }

        return new MappingJacksonInputMessage(new ByteArrayInputStream(bytes), httpInputMessage.getHeaders());
    }

    @Override
    public Object afterBodyRead(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        return o;
    }

    @Override
    public Object handleEmptyBody(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        return o;
    }
}

效果

效果就不展示了,markdown不好贴图。。。感兴趣的小伙伴可以下载代码试试看

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值