问题描述
我有两个与openfeign进行通信的服务(github.openfeign:10.2.0).我正在强制反序列化以JSON发送的数据时间的问题.这是我的配置:
I've got two services that are communicating with openfeign (github.openfeign:10.2.0). I'm forcing problem with deserializing datatime that is sent as JSON.Here is my configuration:
@Configuration
class JacksonConfig : WebMvcConfigurerAdapter() {
override fun extendMessageConverters(converters: List<HttpMessageConverter<*>>?) {
for (converter in converters!!) {
if (converter is MappingJackson2HttpMessageConverter) {
val objectMapper = converter.objectMapper
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
objectMapper.disable(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS)
break
}
}
}
}
private val client = Feign.builder()
.encoder(JacksonEncoder())
.decoder(JacksonDecoder())
.target(Client::class.java, host)
@JsonIgnoreProperties(ignoreUnknown = true)
data class XYZ(
var id: Int? = null,
val X: Int? = null,
val Y: Int? = null,
@Enumerated(EnumType.STRING)
val z: Type? = null,
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss")
val createdOn: LocalDateTime? = null
)
这里是例外:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is feign.FeignException: Can not construct instance of java.time.LocalDateTime: no String-argument constructor/factory method to deserialize from String value ('2019-03-06T16:50:53')
at [Source: java.io.BufferedReader@3c14b300; line: 1, column: 77] (through reference chain: java.util.HashSet[0]->XYZ["createdOn"]) reading GET http://localhost:8080/path] with root cause
com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of java.time.LocalDateTime: no String-argument constructor/factory method to deserialize from String value ('2019-03-06T16:50:53')
at [Source: java.io.BufferedReader@3c14b300; line: 1, column: 77] (through reference chain: java.util.HashSet[0]->XYZ["createdOn"])
这是杰森:
[
{
"id": 2,
"X": 1,
"U": 1,
"Z": "ABC",
"createdOn": "2019-03-06T16:50:53"
}
]
依赖项:
compile group: 'io.github.openfeign', name: 'feign-core', version: '10.2.0'
compile group: 'io.github.openfeign', name: 'feign-jackson', version: '10.2.0'
compile "com.fasterxml.jackson.datatype:jackson-datatype-jdk:$jackson_version"
compile "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:$jackson_version"
compile "com.fasterxml.jackson.module:jackson-module-kotlin:$jackson_config"
推荐答案
当我们看一下 JacksonEncoder
和 JacksonDecoder
已实现,我们会注意到它们在构造函数中创建了新的ObjectMapper
:
public JacksonDecoder(Iterable<Module> modules) {
this(new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.registerModules(modules));
}
默认情况下,使用emptyList()
调用上述构造函数.因此,我们需要提供要手动使用的所有模块.
Above constructor is invoked by default with emptyList()
. So, we need to provide all modules we want to use manually.
要从Java 8
和Jackson
中获得最大收益,请从 jackson-注册所有3个模块modules-java8 :
To get the most from Java 8
and Jackson
register all 3 modules from jackson-modules-java8:
private val client = Feign.builder()
.encoder(JacksonEncoder(Arrays.asList(JavaTimeModule(), ...)))
.decoder(JacksonDecoder(Arrays.asList(JavaTimeModule(), ...)))
.target(Client::class.java, host)
编辑
Ther是一个允许使用ObjectMapper
实例的构造函数.您可以创建新实例或从容器中注入
EDIT
Ther is a constructor which allow to use ObjectMapper
instance. You can create new instance or inject from your container:
val mapper = ObjectMapper()
mapper.registerModule(ParameterNamesModule())
.registerModule(Jdk8Module())
.registerModule(JavaTimeModule())
// other configuration
val client = Feign.builder()
.encoder(JacksonEncoder(mapper))
.decoder(JacksonDecoder(mapper))
.target(Client::class.java, host)
这篇关于假装杰克逊dateTime JsonMappingException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!