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

yhived7q  于 2022-12-10  发布在  Spring
关注(0)|答案(1)|浏览(319)

我知道有一些问题与我的问题重复,但没有一个问题解决了我的问题,因此我创建了一个新问题。
我有一个带有JDK17的spring Boot 应用程序(v 2.7.6),它查询一个ElasticSearch对象。该对象包含一个Instant字段,当Map到Java对象时,该字段会导致以下错误:

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]
...
.....

最初我没有Jackson配置,所以我会认为默认的Jackson将刚刚工作。
在阅读其他stackoverflow的帖子之后,我尝试创建一个这样的配置类,但它并没有解决这个问题:

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;
    }
}

以下也是我的依赖:

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'
}
ux6nzvsh

ux6nzvsh1#

两件事,添加错误日志中提到的依赖项(我看到你已经这样做了),然后在你的spring配置中创建一个objectmapper bean供你的服务使用。请删除上面config类中的内容,并将其简化为以下一个bean方法:

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

相关问题