简体   繁体   English

Spring Boot 2.7.6: Java 8 默认不支持日期/时间类型`java.time.Instant`

[英]Spring Boot 2.7.6: Java 8 date/time type `java.time.Instant` not supported by default

I know there have been a few duplicates of my question but none have resolved my issue so I'm creating a new question.我知道我的问题有一些重复,但没有一个解决了我的问题,所以我创建了一个新问题。

I have a spring boot app (v 2.7.6) with JDK17 which queries an ElasticSearch object. This object contains an Instant field which when being mapped to an Java object is causing the following error:我有一个带有 JDK17 的 spring 引导应用程序 (v 2.7.6),它查询一个 ElasticSearch object。这个 object 包含一个 Instant 字段,当它被映射到一个 Java object 时会导致以下错误:

2022-12-07 00:43:14.442 ERROR 59384 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[.[dispatcherServlet]      : Servlet.service() for servlet [dispatcherServlet] in context with path [/api/v1] threw exception [Request processing failed; nested exception is co.elastic.clients.json.JsonpMappingException: Error deserializing co.elastic.clients.elasticsearch.core.GetResponse: jakarta.json.JsonException: Jackson exception (JSON path: _source) (line no=1, column no=280, offset=-1)] with root cause

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type `java.time.Instant` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling
 at [Source: (org.apache.http.nio.entity.ContentInputStream); line: 1, column: 279] (through reference chain: test.com.model.Project["createdDate"])
    at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67) ~[jackson-databind-2.14.1.jar:2.14.1]
    at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1909) ~[jackson-databind-2.14.1.jar:2.14.1]
    at com.fasterxml.jackson.databind.deser.impl.UnsupportedTypeDeserializer.deserialize(UnsupportedTypeDeserializer.java:48) ~[jackson-databind-2.14.1.jar:2.14.1]
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129) ~[jackson-databind-2.14.1.jar:2.14.1]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:314) ~[jackson-databind-2.14.1.jar:2.14.1]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177) ~[jackson-databind-2.14.1.jar:2.14.1]
    at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:323) ~[jackson-databind-2.14.1.jar:2.14.1]
    at com.fasterxml.jackson.databind.ObjectMapper._readValue(ObjectMapper.java:4706) ~[jackson-databind-2.14.1.jar:2.14.1]
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2879) ~[jackson-databind-2.14.1.jar:2.14.1]
    at co.elastic.clients.json.jackson.JacksonJsonpMapper$JacksonValueParser.deserialize(JacksonJsonpMapper.java:123) ~[elasticsearch-java-8.5.1.jar:na]
    at co.elastic.clients.json.JsonpDeserializer.deserialize(JsonpDeserializer.java:76) ~[elasticsearch-java-8.5.1.jar:na]
    at co.elastic.clients.json.JsonpMapperBase.deserialize(JsonpMapperBase.java:70) ~[elasticsearch-java-8.5.1.jar:na]
    at co.elastic.clients.json.JsonpDeserializer$1.deserialize(JsonpDeserializer.java:99) ~[elasticsearch-java-8.5.1.jar:na]
    at co.elastic.clients.json.NamedDeserializer.deserialize(NamedDeserializer.java:64) ~[elasticsearch-java-8.5.1.jar:na]
    at co.elastic.clients.json.ObjectDeserializer$FieldObjectDeserializer.deserialize(ObjectDeserializer.java:78) ~[elasticsearch-java-8.5.1.jar:na]
    at co.elastic.clients.json.ObjectDeserializer.deserialize(ObjectDeserializer.java:192) ~[elasticsearch-java-8.5.1.jar:na]
    at co.elastic.clients.json.ObjectDeserializer.deserialize(ObjectDeserializer.java:148) ~[elasticsearch-java-8.5.1.jar:na]
    at co.elastic.clients.json.JsonpDeserializer.deserialize(JsonpDeserializer.java:76) ~[elasticsearch-java-8.5.1.jar:na]
    at co.elastic.clients.json.ObjectBuilderDeserializer.deserialize(ObjectBuilderDeserializer.java:79) ~[elasticsearch-java-8.5.1.jar:na]
    at co.elastic.clients.json.DelegatingDeserializer$SameType.deserialize(DelegatingDeserializer.java:43) ~[elasticsearch-java-8.5.1.jar:na]
    at co.elastic.clients.json.DelegatingDeserializer$SameType.deserialize(DelegatingDeserializer.java:43) ~[elasticsearch-java-8.5.1.jar:na]
    at co.elastic.clients.transport.endpoints.EndpointWithResponseMapperAttr$1.deserialize(EndpointWithResponseMapperAttr.java:56) ~[elasticsearch-java-8.5.1.jar:na]
    at co.elastic.clients.transport.rest_client.RestClientTransport.decodeResponse(RestClientTransport.java:325) ~[elasticsearch-java-8.5.1.jar:na]
    at co.elastic.clients.transport.rest_client.RestClientTransport.getHighLevelResponse(RestClientTransport.java:295) ~[elasticsearch-java-8.5.1.jar:na]
    at co.elastic.clients.transport.rest_client.RestClientTransport.performRequest(RestClientTransport.java:148) ~[elasticsearch-java-8.5.1.jar:na]
    at co.elastic.clients.elasticsearch.ElasticsearchClient.get(ElasticsearchClient.java:831) ~[elasticsearch-java-8.5.1.jar:na]
    at co.elastic.clients.elasticsearch.ElasticsearchClient.get(ElasticsearchClient.java:847) ~[elasticsearch-java-8.5.1.jar:na]
...
.....

Originally I had no JacksonConfiguration so I would have thought the default jackson would have just worked.最初我没有 JacksonConfiguration 所以我认为默认的 jackson 会起作用。

After reading other stackoverflow posts I have tried creating a configuration class like so, but it has not resolved the issue:在阅读了其他 stackoverflow 帖子后,我尝试像这样创建一个配置 class,但它并没有解决问题:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.openapitools.jackson.nullable.JsonNullableModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;

@Configuration
public class JacksonConfiguration {

    private final ObjectMapper objectMapper;

    public JacksonConfiguration(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Bean
    public JavaTimeModule dateTimeModule(){
        return new JavaTimeModule();
    }

    @PostConstruct
    ObjectMapper jacksonObjectMapper() {
        objectMapper.registerModule(new JavaTimeModule());
        objectMapper.registerModule(new JsonNullableModule());
        return objectMapper;
    }
}

Here are also my dependancies:这也是我的依赖项:

dependencies {
    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-data-mongodb'
    implementation group: 'org.springframework.data', name: 'spring-data-elasticsearch', version: '5.0.0'
    implementation 'org.elasticsearch.client:elasticsearch-rest-client:8.5.2'
    implementation 'co.elastic.clients:elasticsearch-java:8.5.1'
    implementation 'org.elasticsearch.client:elasticsearch-rest-high-level-client:7.17.6'
    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-security'
    implementation group: 'org.springframework.security', name: 'spring-security-oauth2-client'
    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-validation'
    implementation group: 'org.springframework.boot', name: 'spring-boot-starter-oauth2-resource-server'
//    implementation("org.springframework.boot:spring-boot-starter-actuator")
    implementation 'org.apache.httpcomponents.client5:httpclient5:5.0.3'
    implementation 'org.springdoc:springdoc-openapi-ui:1.6.13'
    implementation 'org.springdoc:springdoc-openapi-security:1.6.13'
    implementation 'org.springdoc:springdoc-openapi-webmvc-core:1.6.13'
    implementation 'org.springdoc:springdoc-openapi-webflux-core:1.6.13'
    implementation 'org.springdoc:springdoc-openapi-webflux-ui:1.6.13'

    implementation("org.springframework.cloud:spring-cloud-gcp-starter-pubsub:1.2.8.RELEASE")
    implementation("org.springframework.integration:spring-integration-core")
    implementation group: 'org.springframework.cloud', name: 'spring-cloud-gcp-starter-logging'
    implementation group: 'org.springframework.cloud', name: 'spring-cloud-gcp-starter-logging', version: '1.2.8.RELEASE'

    implementation group: 'co.elastic.logging', name: 'logback-ecs-encoder', version: '1.3.2'
    implementation group: 'com.amazonaws', name: 'aws-java-sdk', version: '1.12.142'

    implementation group: 'javax.validation', name: 'validation-api', version: '2.0.1.Final'
//    implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.13.1'
    implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.14.1'
    implementation group: 'io.jsonwebtoken', name: 'jjwt', version: '0.9.1'
    implementation group: 'org.json', name: 'json', version: '20201115'

    implementation group: 'org.openapitools', name: 'jackson-databind-nullable', version: '0.2.2'
    implementation 'com.fasterxml.jackson.core:jackson-databind:2.14.1'
    implementation 'jakarta.json:jakarta.json-api:2.0.1'

    implementation group: 'org.apache.commons', name: 'commons-collections4', version: '4.4'
    implementation 'commons-io:commons-io:2.11.0'
    implementation 'org.apache.commons:commons-lang3:3.12.0'
    implementation 'com.google.guava:guava:31.0.1-jre'

    implementation group: 'com.auth0', name: 'java-jwt', version: '3.12.0'
    implementation group: 'com.auth0', name: 'auth0', version: '1.34.1'
    annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"


    implementation group: 'commons-codec', name: 'commons-codec', version: '1.15'
    compileOnly 'org.projectlombok:lombok:1.18.24'
    annotationProcessor 'org.projectlombok:lombok:1.18.22'

    implementation 'org.springframework.boot:spring-boot-starter-web'
    testImplementation group: 'junit', name: 'junit', version: '4.13.2'
    testImplementation 'org.projectlombok:lombok:1.18.20'
    testAnnotationProcessor 'org.projectlombok:lombok:1.18.20'
    testImplementation 'org.junit.jupiter:junit-jupiter-api'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
}

Two things, add the dependency the error log talks about (which I see you did) and then create a objectmapper bean in your spring configs for your service to use.两件事,添加错误日志谈论的依赖项(我看到你做了),然后在你的 spring 配置中创建一个 objectmapper bean 供你的服务使用。 Please remove what you have in the config class above and simply it to just this one bean method:请删除您在上面的配置 class 中拥有的内容,并将其简化为仅此一个 bean 方法:

@Bean
ObjectMapper jacksonObjectMapper() {
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.registerModule(new JavaTimeModule());
    return objectMapper;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Spring Boot 2.5.0 and InvalidDefinitionException: Java 8 日期/时间类型 `java.time.Instant` 默认不支持 - Spring Boot 2.5.0 and InvalidDefinitionException: Java 8 date/time type `java.time.Instant` not supported by default 将 Spring 从 2.4.1 升级到 2.6.1,默认不支持 `java.time.Instant` 错误 - Upgrading Spring Boot from 2.4.1 to 2.6.1, getting `java.time.Instant` not supported by default error java.time.即时响应 JavaScript 日期 - java.time.Instant response to JavaScript date 为什么Hibernate 5.2支持java.time.Instant,而JPA 2不支持? - Why java.time.Instant is supported in Hibernate 5.2 but not in JPA 2? 为什么不向java.time.Instant添加周数? - Why is adding weeks to java.time.Instant not supported? Mysql 8.0 JDBC 类型 java.time.Instant 使用 JdbcTemplate 不支持转换 - Mysql 8.0 JDBC Conversion not supported for type java.time.Instant using JdbcTemplate Spring Boot - Jersey 客户端 - Jackson 无法构造 `java.time.Instant` 的实例 - Spring Boot - Jersey Client - Jackson Cannot construct instance of `java.time.Instant` 如何在 Spring Webflux 中将 java.time.Instant 序列化为 ISO 字符串 - How to serialize java.time.Instant as ISO string in Spring Webflux Spring MockMvc - 从REST获取java.time.Instant - Spring MockMvc - getting java.time.Instant from REST 无法反序列化`java.time.Instant`类型的值 - jackson - Cannot deserialize value of type `java.time.Instant` - jackson
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM