0

0

反序列化 LocalDateTime 时出现问题:Jackson InvalidFormatException

王林

王林

发布时间:2024-02-22 13:58:06

|

551人浏览过

|

来源于stackoverflow

转载

php小编子墨为您带来关于java反序列化localdatetime时出现问题的解决方法。在使用jackson库进行反序列化时,有时会遇到invalidformatexception的异常,特别是在处理localdatetime类型时更为常见。本文将详细介绍该问题的原因和解决方案,帮助您顺利解决这一常见的反序列化异常。

问题内容

我在 spring boot 应用程序中反序列化 localdatetime 时遇到问题。下面是相关代码。

前端:

update(lancamento: lancamento): promise {
      const headers = new httpheaders()
        .set('authorization', this.chave)
        .set('content-type', 'application/json');

        this.conversordedata([lancamento]);

        return firstvaluefrom(this.http.put(`${this.url}/${lancamento.codigo}`,
      lancamento, { headers }));
    }

    findbycode(codigo: number): promise {
      const headers = new httpheaders()
        .set('authorization', this.chave);

      return this.http.get(`${this.url}/${codigo}`,
        { headers })
        .topromise()
        .then((response: any) => {
          const lancamento = response as lancamento;

          this.conversordedata([lancamento]);

          return lancamento;
        })
        .catch((error: any) => {
          console.error('erro ao buscar lançamento por código: ', error);
          throw error;
        });
    }

//se os atributos forem do tipo date
conversordedata(lancamentos: lancamento[]){
  for(const lancamento of lancamentos){
    if(lancamento.datavencimento && isvalid(lancamento.datavencimento)){
      lancamento.datavencimento = new date(format(lancamento.datavencimento, 'dd/mm/yyyy'));
    }
    if(lancamento.datapagamento && isvalid(lancamento.datapagamento)){
      lancamento.datapagamento = new date(format(lancamento.datapagamento, 'dd/mm/yyyy'));
    }

  }
}

后端:lancamento 类:

package com.algaworks.algamoney_api.domain.model;

import com.fasterxml.jackson.annotation.jsonformat;
import jakarta.persistence.*;
import jakarta.validation.constraints.notnull;
import org.springframework.format.annotation.datetimeformat;

import java.math.bigdecimal;
import java.time.localdate;
import java.time.localdatetime;
import java.util.objects;

@entity
@table(name = "lancamento")
public class lancamento {

    @id
    @generatedvalue(strategy = generationtype.identity)
    private integer codigo;

    @notnull
    private string descricao;

    @column(name = "data_vencimento")
    @jsonformat(pattern = "dd/mm/yyyy")
    private localdatetime datavencimento;

    @column(name = "data_pagamento")
    @jsonformat(pattern = "dd/mm/yyyy")
    private localdatetime datapagamento;

    @notnull
    private bigdecimal valor;
    private string observacao;

    @notnull
    @enumerated(enumtype.string)
    private tipolancamento tipo;

    @notnull
    @manytoone // vários lançamentos podem estar em uma categoria
    @joincolumn(name = "codigo_categoria")
    private categoria categoria;

    @notnull
    @manytoone
    @joincolumn(name = "codigo_pessoa")
    private pessoa pessoa;

    public integer getcodigo() {
        return codigo;
    }

    public void setcodigo(integer codigo) {
        this.codigo = codigo;
    }

    public string getdescricao() {
        return descricao;
    }

    public void setdescricao(string descricao) {
        this.descricao = descricao;
    }

    public localdatetime getdatavencimento() {
        return datavencimento;
    }

    public void setdatavencimento(localdatetime datavencimento) {
        this.datavencimento = datavencimento;
    }

    public localdatetime getdatapagamento() {
        return datapagamento;
    }

    public void setdatapagamento(localdatetime datapagamento) {
        this.datapagamento = datapagamento;
    }

    public bigdecimal getvalor() {
        return valor;
    }

    public void setvalor(bigdecimal valor) {
        this.valor = valor;
    }

    public string getobservacao() {
        return observacao;
    }

    public void setobservacao(string observacao) {
        this.observacao = observacao;
    }

    public tipolancamento gettipo() {
        return tipo;
    }

    public void settipo(tipolancamento tipo) {
        this.tipo = tipo;
    }

    public categoria getcategoria() {
        return categoria;
    }

    public void setcategoria(categoria categoria) {
        this.categoria = categoria;
    }

    public pessoa getpessoa() {
        return pessoa;
    }

    public void setpessoa(pessoa pessoa) {
        this.pessoa = pessoa;
    }

    @override
    public boolean equals(object o) {
        if (this == o) return true;
        if (o == null || getclass() != o.getclass()) return false;
        lancamento that = (lancamento) o;
        return codigo.equals(that.codigo);
    }

    @override
    public int hashcode() {
        return objects.hash(codigo);
    }
}

resumolancamento 类:

package com.algaworks.algamoney_api.repository.projection;

import com.algaworks.algamoney_api.domain.model.tipolancamento;

import java.math.bigdecimal;
import java.time.localdate;
import java.time.localdatetime;

/**
 * 7.1. implementando projeção de lançamento*/

public class resumolancamento {

    private integer codigo;
    private string descricao;
    private localdatetime datavencimento;
    private localdatetime datapagamento;
    private bigdecimal valor;
    private tipolancamento tipo;
    private string categoria;
    private string pessoa;

    public resumolancamento(integer codigo, string descricao, localdatetime datavencimento, localdatetime datapagamento, bigdecimal valor, tipolancamento tipo, string categoria, string pessoa) {
        this.codigo = codigo;
        this.descricao = descricao;
        this.datavencimento = datavencimento;
        this.datapagamento = datapagamento;
        this.valor = valor;
        this.tipo = tipo;
        this.categoria = categoria;
        this.pessoa = pessoa;
    }

    public integer getcodigo() {
        return codigo;
    }

    public void setcodigo(integer codigo) {
        this.codigo = codigo;
    }

    public string getdescricao() {
        return descricao;
    }

    public void setdescricao(string descricao) {
        this.descricao = descricao;
    }

    public localdatetime getdatavencimento() {
        return datavencimento;
    }

    public void setdatavencimento(localdatetime datavencimento) {
        this.datavencimento = datavencimento;
    }

    public localdatetime getdatapagamento() {
        return datapagamento;
    }

    public void setdatapagamento(localdatetime datapagamento) {
        this.datapagamento = datapagamento;
    }

    public bigdecimal getvalor() {
        return valor;
    }

    public void setvalor(bigdecimal valor) {
        this.valor = valor;
    }

    public tipolancamento gettipo() {
        return tipo;
    }

    public void settipo(tipolancamento tipo) {
        this.tipo = tipo;
    }

    public string getcategoria() {
        return categoria;
    }

    public void setcategoria(string categoria) {
        this.categoria = categoria;
    }

    public string getpessoa() {
        return pessoa;
    }

    public void setpessoa(string pessoa) {
        this.pessoa = pessoa;
    }
}

问题:

com.fasterxml.jackson.databind.exc.invalidformatexception:无法从字符串“10/01/2024”反序列化 java.time.localdatetime 类型的值:无法反序列化 java.time.localdatetime:(java.time.format .datetimeparseexception)无法解析文本“10/01/2024”:无法从 temporalaccessor 获取 localdatetime:{},iso 解析为 java.time.format.parsed 类型的 2024-01-10 在[来源:(org.springframework.util.streamutils$nonclosinginputstream);行:1,列:63](通过参考链:com.algaworks.algamoney_api.domain.model.lancamento[“datavencimento”])

lancamentos的console.log()中,属性“datavencimento”和“datapagamento”的格式为“dd/mm/yyyy”。

我怀疑反序列化期间存在日期格式问题。尽管更新了前端和后端代码,问题仍然存在。我相信问题出在客户身上,我不知道。

LangChain
LangChain

一个开源框架,用于构建基于大型语言模型(LLM)的应用程序。

下载
  1. 在 spring boot 应用程序中从字符串反序列化 localdatetime 时,如何修复 invalidformatexception?
  2. 正确的 localdatetime 序列化和反序列化是否需要特定的配置或调整?

如有任何指导或建议,我们将不胜感激。谢谢!

我用 dataconverter() 方法做了所有事情,但仍然没有成功。

conversorDeData(lancamentos: Lancamento[]){
  for(const lancamento of lancamentos){
    if(lancamento.dataVencimento && isValid(lancamento.dataVencimento)){
      lancamento.dataVencimento = new Date(format(lancamento.dataVencimento, 'dd/MM/yyyy'));
    }
    if(lancamento.dataPagamento && isValid(lancamento.dataPagamento)){
      lancamento.dataPagamento = new Date(format(lancamento.dataPagamento, 'dd/MM/yyyy'));
    }

  }
}

解决方法

要解决此问题,您可以执行以下操作之一:

选项 1:调整 json 日期格式 更改 json 负载中的日期格式以匹配模式“yyyy-mm-ddthh:mm:ss”或与 localdatetime 直接兼容的任何格式。例如:

{
  "codigo": 1,
  "descricao": "sample description",
  "datavencimento": "2024-01-10t00:00:00",
  "datapagamento": "2024-01-10t00:00:00",
  "valor": 100.0,
  "observacao": "sample observation",
  "tipo": "sample_type",
  "categoria": {
    "codigo": 1
  },
  "pessoa": {
    "codigo": 1
  }
}

选项2:使用@jsondeserialize指定自定义反序列化格式 您可以使用 @jsondeserialize 注释 lancamento 类中的 localdatetime 字段,以指定自定义反序列化格式。例如:

import com.fasterxml.jackson.databind.annotation.jsondeserialize;
import com.fasterxml.jackson.datatype.jsr310.deser.localdatetimedeserializer;
// other imports...

@entity
@table(name = "lancamento")
public class lancamento {
    // ... other fields

    @column(name = "data_vencimento")
    @jsondeserialize(using = localdatetimedeserializer.class)
    private localdatetime datavencimento;

    @column(name = "data_pagamento")
    @jsondeserialize(using = localdatetimedeserializer.class)
    private localdatetime datapagamento;

    // ... other methods
}

请记住调整 json 负载中的反序列化格式或日期格式,以确保它们正确对齐。选择最适合您的要求和编码实践的方法。

选项 3:出现此问题的原因是 java 中的 localdatetime 没有针对包含日期和时间组件的模式“dd/mm/yyyy”的直接格式化程序。如果您只对日期组件感兴趣,您可能需要将这些字段的类型更改为 localdate。

//...

@Column(name = "data_vencimento")
@JsonFormat(pattern = "dd/MM/yyyy")
private LocalDate dataVencimento;

@Column(name = "data_pagamento")
@JsonFormat(pattern = "dd/MM/yyyy")
private LocalDate dataPagamento;

//...

public LocalDate getDataVencimento() {
    return dataVencimento;
}

public void setDataVencimento(LocalDate dataVencimento) {
    this.dataVencimento = dataVencimento;
}

public LocalDate getDataPagamento() {
    return dataPagamento;
}

public void setDataPagamento(LocalDate dataPagamento) {
    this.dataPagamento = dataPagamento;
}

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

832

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

738

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

734

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

397

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

398

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

446

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

430

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16925

2023.08.03

Golang gRPC 服务开发与Protobuf实战
Golang gRPC 服务开发与Protobuf实战

本专题系统讲解 Golang 在 gRPC 服务开发中的完整实践,涵盖 Protobuf 定义与代码生成、gRPC 服务端与客户端实现、流式 RPC(Unary/Server/Client/Bidirectional)、错误处理、拦截器、中间件以及与 HTTP/REST 的对接方案。通过实际案例,帮助学习者掌握 使用 Go 构建高性能、强类型、可扩展的 RPC 服务体系,适用于微服务与内部系统通信场景。

4

2026.01.15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号