当使用Spring Cloud Feign传递日期类型参数时可能会遇到以下错误:
java.lang.IllegalArgumentException: Could not read document: Invalid format: "2019-08-30T09:30:00.000Z" is malformed at "T09:30:00.000Z"
这是因为Feign的默认编码器在将日期转换为JSON字符串时,使用了错误的格式。但是,我们可以通过自定义编码器来解决这个问题。
以下是解决这个问题的完整攻略:
- 添加依赖
为了解决这个问题,我们需要添加几个依赖:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
- 自定义配置日期格式
创建一个用于解析日期格式的配置类:
import java.time.format.DateTimeFormatter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
@Configuration
public class DateConfiguration {
@Bean
public ObjectMapper objectMapper() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(new LocalDateTimeSerializer(formatter));
ObjectMapper objectMapper = new ObjectMapper();
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(new LocalDateTimeSerializer(formatter));
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.registerModule(javaTimeModule);
objectMapper.registerModule(simpleModule);
return objectMapper;
}
}
- 配置Feign编码器
创建一个自定义的Feign编码器来序列化和反序列化日期类型数据:
import java.lang.reflect.Type;
import java.time.LocalDateTime;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.context.annotation.Bean;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.google.common.collect.Lists;
import feign.codec.EncodeException;
import feign.codec.Encoder;
import feign.form.spring.SpringFormEncoder;
public class FeignDateEncoder {
@Bean
public Encoder feignEncoder() {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(new SpringEncoder(Lists.newArrayList(new SpringFormEncoder(new SpringEncoder(objectFactory)))));
return new Encoder() {
private final SpringEncoder delegate = new SpringEncoder(objectFactory);
@Override
public void encode(Object object, Type bodyType, feign.RequestTemplate template) throws EncodeException {
if (object instanceof LocalDateTime) {
String text = objectMapper.writeValueAsString(object);
template.body(text);
} else {
delegate.encode(object, bodyType, template);
}
}
};
}
}
- 注册自定义Feign编码器
在启动类上注册自定义的Feign编码器:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients(defaultConfiguration = { FeignDateEncoder.class })
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
现在,就可以在Feign客户端中传递日期类型参数了,如下例:
@RequestMapping(value = "/api/user", method = RequestMethod.GET)
public void getUserByCreateTimeBetween(@RequestParam(name = "start") LocalDateTime start, @RequestParam(name = "end") LocalDateTime end);
FeignClient.getUserByCreateTimeBetween(LocalDateTime.of(2019, 8, 31, 0, 0), LocalDateTime.of(2019, 9, 1, 0, 0))
以上就是使用Spring Cloud Feign在传递日期类型参数时报错的解决方案,希望能对你有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Springcloud feign传日期类型参数报错的解决方案 - Python技术站