首页 > 解决方案 > Spring Boot 在运行时操作 http 参数

问题描述

我正在尝试在最终端点接收到呼叫之前操纵一些http参数(在查询中,正文...),但没有成功。例如,我们有这个帖子调用:

curl -X POST "http://localhost:8080/insertBody/" -H "accept: application/json" -H "Content-Type: application/json" -H "Date-Format: yyyy-MM-dd" -d "{ \"isUniform\": true, \"myDate\": \"2020-01-14T08:55:07.013Z\", \"myInt\": 0, \"uniform\": true}"

我想要做的是将myDate -> 2020-01-14T08:55:07.013Z以这种格式在标题中传递的yyyy-MM-dd转换为帖子正文。操作必须涉及此调用中存在的所有OffsetDateTime类型的对象(在这种情况下)。

当微服务收到调用时:

Header:
  Date-Format: yyyy-MM-dd
Body
  {
    "isUniform": true,
    "myDate": "2020-01-14T08:55:07.013Z",
    "myInt": 0,
    "uniform": true
  }

在数据操作和控制器接收到的内容之后:

Header:
  Date-Format: yyyy-MM-dd
Body
  {
    "isUniform": true,
    "myDate": "2020-01-14",   <---
    "myInt": 0,
    "uniform": true
  }

身体类

public class CashBackCampaignRequest   {

  @JsonProperty("uniform")
  private Boolean uniform = true;

  @JsonProperty("myInt")
  private Integer myInt = null;

  @JsonProperty("myDate")
  private OffsetDateTime myDate = null;

  // getter setters ...
}

标签: restspring-bootspring-mvcjava-8interceptor

解决方案


你应该使用著名的RequestBodyAdviceAdapter. 在进入控制器之前,您可以操作消息的正文。你声明一个@ControllerAdvice@RestControllerAdvice(它只是一个@Component),并扩展类RequestBodyAdviceAdapter。(您也可以实现接口RequestBodyAdvice,但我建议扩展抽象类)。

这是一个简单的例子:

@RestControllerAdvice
public class WebAdvice extends RequestBodyAdviceAdapter {

    @Override
    public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
        // to know whether you will use your advice or not
        return true;
    }

    @Override
    public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
        String format = inputMessage.getHeaders().get("DATE_FORMAT").get(0);
        if(body instanceof CashBackCampaignRequest) {
            // Do whatever you want
            ((CashBackCampaignRequest) body).setDate()
        }
        return super.afterBodyRead(body, inputMessage, parameter, targetType, converterType);
    }
}

请注意在Controller. 如果您的控制器收到一个类型为 的对象CashBackCampaignRequest,那么您将无法更改格式。


推荐阅读