默认情况下,feign使用
org.springframework.cloud.openfeign.support.SpringDecoder
,默认使用的jackson反序列化对象,不做任何处理的话,会报序列化异常问题。部分异常信息如下:nested exception is >org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `java.time.LocalDateTime` from >String "2020-11-04 14:43:37": Failed to deserialize java.time.LocalDateTime: (java.time.format.DateTimeParseException)
我们可以将Decoder替换成Gson,通过配置java8时间类的序列化规则使其支持反序列化java8时间类对象
- 引入Feign的Gson支持
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-gson</artifactId>
</dependency>
- 配置Encoder,Decoder序列化类,指定为Gson
@Configuration
public class FeignCodecConfiguration {
private static final String DEFAULT_DATE_TIME_FORMATTER = "yyyy-MM-dd HH:mm:ss";
private static final String DEFAULT_DATE_FORMATTER = "yyyy-MM-dd";
private static final String DEFAULT_TIME_FORMATTER = "HH:mm:ss";
private static final Gson gson = GSON = new GsonBuilder()
.serializeNulls()
.registerTypeAdapter(LocalDateTime.class, (JsonSerializer<LocalDateTime>) (localDateTime, typeOfSrc, context) -> {
if (Objects.isNull(localDateTime)) {
return new JsonPrimitive("");
}
return new JsonPrimitive(localDateTime.format(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMATTER)));
})
.registerTypeAdapter(LocalDateTime.class, (JsonDeserializer<LocalDateTime>) (json1, typeOfT, context) -> {
String string = json1.getAsJsonPrimitive().getAsString();
if (Strings.isNullOrEmpty(string)) {
return null;
}
return LocalDateTime.parse(string, DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMATTER));
})
.registerTypeAdapter(LocalDate.class, (JsonSerializer<LocalDate>) (localDate, type, jsonSerializationContext) -> {
if (Objects.isNull(localDate)) {
return new JsonPrimitive("");
}
return new JsonPrimitive(localDate.format(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMATTER)));
})
.registerTypeAdapter(LocalDate.class, (JsonDeserializer<LocalDate>) (json, typeOfT, context) -> {
String string = json.getAsJsonPrimitive().getAsString();
if (Strings.isNullOrEmpty(string)) {
return null;
}
return LocalDate.parse(string, DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMATTER));
})
.registerTypeAdapter(LocalTime.class, (JsonSerializer<LocalTime>) (localTime, type, jsonSerializationContext) -> {
if (Objects.isNull(localTime)) {
return new JsonPrimitive("");
}
return new JsonPrimitive(localTime.format(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMATTER)));
})
.registerTypeAdapter(LocalTime.class, (JsonDeserializer<LocalTime>) (json, typeOfT, context) -> {
String string = json.getAsJsonPrimitive().getAsString();
if (Strings.isNullOrEmpty(string)) {
return null;
}
return LocalTime.parse(string, DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMATTER));
})
.create();
PRETTY_GSON = new GsonBuilder()
.serializeNulls()
.registerTypeAdapter(LocalDateTime.class, (JsonSerializer<LocalDateTime>) (localDateTime, typeOfSrc, context) -> {
if (Objects.isNull(localDateTime)) {
return new JsonPrimitive("");
}
return new JsonPrimitive(localDateTime.format(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMATTER)));
})
.registerTypeAdapter(LocalDateTime.class, (JsonDeserializer<LocalDateTime>) (json1, typeOfT, context) -> {
String string = json1.getAsJsonPrimitive().getAsString();
if (Strings.isNullOrEmpty(string)) {
return null;
}
return LocalDateTime.parse(string, DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMATTER));
})
.registerTypeAdapter(LocalDate.class, (JsonSerializer<LocalDate>) (localDate, type, jsonSerializationContext) -> {
if (Objects.isNull(localDate)) {
return new JsonPrimitive("");
}
return new JsonPrimitive(localDate.format(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMATTER)));
})
.registerTypeAdapter(LocalDate.class, (JsonDeserializer<LocalDate>) (json, typeOfT, context) -> {
String string = json.getAsJsonPrimitive().getAsString();
if (Strings.isNullOrEmpty(string)) {
return null;
}
return LocalDate.parse(string, DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMATTER));
})
.registerTypeAdapter(LocalTime.class, (JsonSerializer<LocalTime>) (localTime, type, jsonSerializationContext) -> {
if (Objects.isNull(localTime)) {
return new JsonPrimitive("");
}
return new JsonPrimitive(localTime.format(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMATTER)));
})
.registerTypeAdapter(LocalTime.class, (JsonDeserializer<LocalTime>) (json, typeOfT, context) -> {
String string = json.getAsJsonPrimitive().getAsString();
if (Strings.isNullOrEmpty(string)) {
return null;
}
return LocalTime.parse(string, DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMATTER));
})
.setPrettyPrinting()
.create();
@Bean
public GsonDecoder gsonDecoder() {
return new GsonDecoder(gson);
}
@Bean
public GsonEncoder gsonEncoder() {
return new GsonEncoder(gson);
}
}