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}"

我正在尝试做的是在标题中传递的这种格式yyyy-MM-dd转换帖子正文内的myDate -> 2020-01-14T08:55:07.013Z。操作必须涉及此调用中存在的所有类型为 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 ...
}

你应该使用著名的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的对象,您将无法更改格式。

基于 RUARDO ansare 我可以使用ResponseBodyAdvice<对象来获取 RequestBodyAdviceAdapter=">

@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;
}
}

最新更新