如何在Feign Client中配置请求体日期的指定格式序列化?
Feign Client日期序列化格式配置问题解决
问题描述
用Feign Client调用第三方API时,请求体里的日期格式是这样的:
{ "requestTime": "2023-06-07T12:18:00.916+00:00" }
但第三方API只认yyyy-MM-dd'T'HH:mm:ss.SSSZ格式的日期,合法的请求体示例是:
{ "requestTime": "2023-06-17T14:53:47.402Z" }
现有代码
Feign Client接口
@FeignClient(value = "myfeign", url = "https://myfeign.com/") public interface MyFeignClient { @PostMapping(value = "/myfeign/", produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE) MyResponse sendRequest(MyRequest request); }
openapi-generator生成的MyRequest类
public class MyRequest { @JsonProperty("requestTime") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) private Date requestTime; // getter... }
尝试过的无效配置
Feign配置类
public class MyFeignConfig { @Bean public Encoder feignEncoder() { HttpMessageConverter<Object> jacksonConverter = new MappingJackson2HttpMessageConverter(objectMapper()); HttpMessageConverters httpMessageConverters = new HttpMessageConverters(jacksonConverter); ObjectFactory<HttpMessageConverters> objectFactory = () -> httpMessageConverters; return new SpringEncoder(objectFactory); } private ObjectMapper objectMapper() { final String DATE_FORMAT = "yyyy-MM-dd'T'mm:HH:ss.SSSZ"; SimpleDateFormat dateFormat = new SimpleDateFormat((DATE_FORMAT)); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setDateFormat(dateFormat); } }
修改后的Feign Client
@FeignClient(value = "myfeign", url = "https://myfeign.com/", configuration = "MyFeignConfig.class") public interface MyFeignClient { @PostMapping(value = "/myfeign/", produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE) MyResponse sendRequest(MyRequest request); }
问题分析
- 日期格式写错了:你配置的
DATE_FORMAT把小时和分钟的格式搞反了,应该是HH:mm(24小时制小时在前),不是mm:HH,正确格式是yyyy-MM-dd'T'HH:mm:ss.SSSZ。 - ObjectMapper没返回:
objectMapper()方法最后没返回配置好的ObjectMapper实例,等于白配置了。 - FeignClient配置引用错误:
configuration属性要传类对象MyFeignConfig.class,不是字符串"MyFeignConfig.class"。 - @DateTimeFormat没用:这个注解是Spring MVC用来绑定请求参数的,对Jackson序列化日期根本不起作用,得用Jackson的注解。
解决步骤
1. 修正Feign配置类
把格式写错的地方改过来,还要记得返回ObjectMapper:
public class MyFeignConfig { @Bean public Encoder feignEncoder() { HttpMessageConverter<Object> jacksonConverter = new MappingJackson2HttpMessageConverter(objectMapper()); HttpMessageConverters httpMessageConverters = new HttpMessageConverters(jacksonConverter); ObjectFactory<HttpMessageConverters> objectFactory = () -> httpMessageConverters; return new SpringEncoder(objectFactory); } private ObjectMapper objectMapper() { final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"; SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setDateFormat(dateFormat); // 必须返回配置好的ObjectMapper return objectMapper; } }
2. 修正FeignClient的配置引用
去掉configuration属性的引号,直接传类对象:
@FeignClient(value = "myfeign", url = "https://myfeign.com/", configuration = MyFeignConfig.class) public interface MyFeignClient { @PostMapping(value = "/myfeign/", produces = APPLICATION_JSON_VALUE, consumes = APPLICATION_JSON_VALUE) MyResponse sendRequest(MyRequest request); }
3. 给MyRequest加Jackson注解(可选但更稳妥)
为了避免全局配置被其他地方覆盖,直接在MyRequest的日期字段上加Jackson的@JsonFormat注解,明确指定序列化格式:
public class MyRequest { @JsonProperty("requestTime") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = "GMT") private Date requestTime; // getter... }
4. 验证结果
配置完之后,请求体里的日期就会变成符合要求的格式:
{ "requestTime": "2023-06-17T14:53:47.402Z" }
内容的提问来源于stack exchange,提问作者ikhvjs
相关产品推荐
相关产品推荐

