Rumah  >  Artikel  >  Masalah menyahsiri LocalDateTime: Jackson InvalidFormatException

Masalah menyahsiri LocalDateTime: Jackson InvalidFormatException

王林
王林ke hadapan
2024-02-22 13:58:06357semak imbas

Editor PHP Zimo membawakan anda penyelesaian kepada masalah apabila Java menyahsiri LocalDateTime. Apabila menggunakan perpustakaan Jackson untuk penyahserialisasian, anda kadangkala menghadapi pengecualian InvalidFormatException, terutamanya apabila berurusan dengan jenis LocalDateTime. Artikel ini akan memperkenalkan punca dan penyelesaian masalah ini secara terperinci untuk membantu anda berjaya menyelesaikan pengecualian penyahserikatan biasa ini.

Kandungan soalan

Saya menghadapi masalah menyahsiri localdatetime dalam aplikasi but spring. Di bawah ialah kod yang berkaitan.

Halaman hadapan:

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

        this.conversordedata([lancamento]);

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

    findbycode(codigo: number): promise<lancamento> {
      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'));
    }

  }
}

Belakang: lancamento Kelas:

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 Kategori:

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

Soalan:

com.fasterxml.jackson.databind.exc.invalidformatexception: Tidak dapat menyahsiri daripada rentetan "10/01/2024" Nilai jenis java.time.localdatetime: Tidak dapat menyahsiri java.time.localdatetime: (java.time.format .datetimeparseexception ) Tidak dapat menghuraikan teks '10/01/2024': Tidak dapat mendapatkan localdatetime daripada temporalaccessor: {}, iso dihuraikan sebagai 2024-01-10 jenis java.time.format.parsed Dalam [Sumber: (org.springframework.util.streamutils$nonclosinginputstream baris: 1, lajur: 63] (melalui rantaian rujukan: com.algaworks.algamoney_api.domain.model.lancamento["datavencimento"])

Dalam console.log() lancamentos, format atribut "datavencimento" dan "datapagamento" ialah "dd/mm/yyyy".

Saya mengesyaki terdapat isu format tarikh semasa penyahserikatan. Walaupun mengemas kini kod bahagian hadapan dan hujung belakang, masalah itu berterusan. Saya percaya masalahnya adalah pada klien, saya tidak tahu.

  1. Bagaimana untuk membetulkan invalidformatexception apabila menyahsiri localdatetime daripada rentetan dalam aplikasi but spring?
  2. Adakah siri localdatetime yang betul dan penyahsirilan memerlukan konfigurasi atau penalaan khusus?

Sebarang panduan atau cadangan amat kami hargai. Terima kasih!

Saya melakukan segala-galanya dengan kaedah penukar data() tetapi masih tidak berjaya.

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

  }
}

Penyelesaian

Untuk menyelesaikan isu ini, anda boleh melakukan salah satu daripada yang berikut:

Pilihan 1: Laraskan format tarikh json Tukar format tarikh dalam muatan json agar sepadan dengan corak "yyyy-mm-ddthh:mm:ss" atau mana-mana format yang serasi secara langsung dengan localdatetime. Contohnya:

{
  "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
  }
}

Pilihan 2: Gunakan @jsondeserialize untuk menentukan format penyahserikatan tersuai Anda boleh menganotasi medan localdatetime dalam kelas lancamento dengan @jsondeserialize untuk menentukan format penyahserikatan tersuai. Contohnya:

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
}

Ingat untuk melaraskan format penyahserikatan atau format tarikh dalam muatan json untuk memastikan ia diselaraskan dengan betul. Pilih kaedah yang paling sesuai dengan keperluan dan amalan pengekodan anda.

Pilihan 3: Masalah ini berlaku kerana localdatetime dalam java tidak mempunyai pemformat langsung untuk corak "dd/mm/yyyy" yang mengandungi komponen tarikh dan masa. Jika anda hanya berminat dengan komponen tarikh, anda mungkin perlu menukar jenis medan ini kepada 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;
}

Atas ialah kandungan terperinci Masalah menyahsiri LocalDateTime: Jackson InvalidFormatException. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam