【问题标题】:Spring Boot manipulate http parameters on runtimeSpring Boot 在运行时操作 http 参数
【发布时间】:2020-01-14 17:03:41
【问题描述】:

我正在尝试在最终端点接收到调用之前操纵一些 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 ...
}

【问题讨论】:

  • 能否请您发布您的entitymyDate 字段?看起来您将其格式化为 date yyyy-MM-dd
  • 感谢您的回复。不要专注于日期时间对话,我想要的是对所有对象类型执行一些特定操作。示例:查找所有字符串并在末尾添加一个空格@Oneguy
  • 加在头上@JsonFormat(pattern="yyyy-MM-dd'T'HH:mm")
  • 不,我需要动态的,格式在header中传递,每次都不一样@Oneguy

标签: rest spring-boot spring-mvc java-8 interceptor


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    基于 RUARDO answere,我使用 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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-07-11
      • 1970-01-01
      • 2017-11-03
      • 2016-07-13
      • 2019-04-30
      • 1970-01-01
      • 2019-11-14
      • 1970-01-01
      • 2017-08-02
      相关资源
      最近更新 更多