我在 Spring Boot 应用程序中反序列化 LocalDateTime 时遇到问题。下面是相关代码。
前端:
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'));
}
}
}
后端: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);
}
}
兰卡门托课程简介:
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”。
我怀疑反序列化期间存在日期格式问题。尽管更新了前端和后端代码,问题仍然存在。我相信问题出在客户身上,我不知道。
如有任何指导或建议,我们将不胜感激。谢谢!
我用 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 负载中的反序列化格式或日期格式,以确保它们正确对齐。选择最适合您的要求和编码实践的方法。