Rest Spring Boot在运行时操作http参数

Rest Spring Boot在运行时操作http参数,rest,spring-boot,spring-mvc,java-8,interceptor,Rest,Spring Boot,Spring Mvc,Java 8,Interceptor,我正在尝试操作查询、正文中的一些http参数,但没有成功。。。在最终端点接收到呼叫之前。例如,我们有一个post call: 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\": \"20

我正在尝试操作查询、正文中的一些http参数,但没有成功。。。在最终端点接收到呼叫之前。例如,我们有一个post call:

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
  }
您应该使用著名的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);
    }
}

请注意控制器中接收到的请求类型。如果您的控制器接收到类型为CashBackCampaignRequest的对象,则您将无法更改格式。

基于RUARDO Answare,我已将RequestBodyAdviceAdapter与ResponseBodyAdvice一起存储


请您发布您的实体的myDate字段,好吗?看起来您将其格式化为日期yyyy-MM-dd谢谢您的回复。不要关注datetime对话,我想要的是对所有对象类型执行一些特定的操作。示例:查找所有字符串并在@OneguyAdd-on-head@JsonFormatpattern=yyyy-MM-dd'T'HH:mmno,我需要它是动态的,格式在头中传递,每次都不同@Oneguy
@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);
    }
}
@ControllerAdvice
public class ResponseJsonFilterAdvice implements ResponseBodyAdvice<Object> {

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        // true if want to use this controller
        return true;
    }

    @Override
    public Object beforeBodyWrite(
            Object body, 
            MethodParameter returnType, 
            MediaType selectedContentType,
            Class<? extends HttpMessageConverter<?>> selectedConverterType, 
            ServerHttpRequest request,
            ServerHttpResponse response) {

        List<String> headers = request.getHeaders().get("X-MY-DATE-FORMAT");
        if(headers == null || headers.isEmpty())
            return body;


        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new JavaTimeModule());  
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(OffsetDateTime.class, new JsonSerializer<OffsetDateTime>() {
            @Override
            public void serialize(OffsetDateTime offsetDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
                jsonGenerator.writeString(DateTimeFormatter.ofPattern(headers.get(0)).format(offsetDateTime));
            }
        });
        objectMapper.registerModule(simpleModule);

        try {
            return objectMapper.writeValueAsString(body);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return body;
    }
}