线程“main”com.fasterxml.jackson.databind.exc.InvalidTypeIdException中的异常:无法解析类型 ID

Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve type id

提问人:Vinicius Candido 提问时间:11/13/2023 更新时间:11/13/2023 访问量:71

问:

我尝试使用 Jackson 使用 Jackson 将我的应用程序数据存储为 Json。到目前为止,一切都很好,但是现在当我尝试存储一个包含对象 arraylist 的类数组时,我遇到了一个奇怪的错误。

这是我的类,问题出在“private ArrayList itensCompra”中

package org.POO_AC2.dominio.compra;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.POO_AC2.dominio.cliente.Cliente;
import org.POO_AC2.dominio.recursos.Json.Json;


@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type") // Notação Json que define como o tipo da classe deve ser armazenado no json

public class Compra {
    private Long Id;
    private String dataCompra;
    private Double valorTotal;
    private Cliente cliente;
    private ArrayList<ItemCompra> itensCompra;
    private int parcelasTotais;
    private int parcelasPagas;

    private String ultimoPagamento;

    public Compra(String dataCompra,Long codigo,  Long idCliente, ArrayList<ItemCompra> itensCompra, int parcelasTotais) throws IOException {
        this.dataCompra = dataCompra;
        this.valorTotal = valorTotal((ArrayList<ItemCompra>) itensCompra);
        this.cliente = procurarCliente(idCliente); // procura o cliente pelo ID passado e o retorna para inicializar a compra.
        this.itensCompra = itensCompra;
        this.parcelasPagas = 0;
        this.parcelasTotais = parcelasTotais;
        this.ultimoPagamento = null;
        this.Id = codigo;
    }

    public Compra() {
    }

    public Long getId() {
        return Id;
    }

    public void setId(Long id) {
        Id = id;
    }

    public String getDataCompra() {
        return dataCompra;
    }

    public void setDataCompra(String dataCompra) {
        this.dataCompra = dataCompra;
    }

    public Double getValorTotal() {
        return valorTotal;
    }

    public void setValorTotal(Double valorTotal) {
        this.valorTotal = valorTotal;
    }

    public Cliente getCliente() {
        return cliente;
    }

    public void setCliente(Cliente cliente) {
        this.cliente = cliente;
    }

    public List<ItemCompra> getItensCompra() {
        return itensCompra;
    }

    public void setItensCompra(ItemCompra itensCompra) {
        this.itensCompra.add(itensCompra);
    }

    public int getParcelasPagas() {
        return parcelasPagas;
    }

    public void setParcelasPagas(int parcelasPagas) {
        this.parcelasPagas = parcelasPagas;
    }

    public int getParcelasTotais() {
        return parcelasTotais;
    }

    public void setParcelasTotais(int parcelasTotais) {
        this.parcelasTotais = parcelasTotais;
    }

    public String getUltimoPagamento() {
        return ultimoPagamento;
    }

    public void setUltimoPagamento(String ultimoPagamento) {
        this.ultimoPagamento = ultimoPagamento;
    }

    //Procura um cliente pelo ID e o retorna para instanciar a compra
    public Cliente procurarCliente(Long id) throws IOException {

        //Fazer método para substituir isso.
        File fileCliente = new File("Cliente.json");
        ArrayList<Cliente> arrayCliente = new ArrayList<>();
        if(!fileCliente.createNewFile() && fileCliente.length()>0){
            arrayCliente.addAll(Json.readAllData(fileCliente,Cliente.class));
        }

        Cliente cliente = null;

        // Encontra o cliente correto baseado no ID
        for (Cliente c: arrayCliente) {
            if(c.getId().compareTo(id) == 0){
                cliente = c;
            }

        }

        return cliente;
    }

    public double valorTotal(ArrayList<ItemCompra> itensCompra){
        double total = 0;
        for (ItemCompra i: itensCompra) {
            total += i.getValorTotal();
        }

        return total;
    }
}

这是我的类 ItemCompra:

package org.POO_AC2.dominio.compra;

import org.POO_AC2.dominio.produto.Produto;
import org.POO_AC2.dominio.recursos.Json.Json;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;



import com.fasterxml.jackson.annotation.JsonFormat;

import com.fasterxml.jackson.annotation.JsonTypeInfo;

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")

public class ItemCompra {
    private int qtde;
    private Long codigoProduto;
    private Double precoUnitario;
    private Double valorTotal;

    public ItemCompra(int qtde, Long codigoProduto) throws IOException {
        Produto p = procurarProdutoPorID(codigoProduto);
        this.qtde = qtde;
        this.codigoProduto = codigoProduto;
        this.precoUnitario = p.getPreco();
        this.valorTotal = p.getPreco() * qtde;
    }

    public ItemCompra() {
    }

    public ItemCompra(Produto selectedProduto, int quantidade) {
    }

    public int getQtde(){
        return qtde;
    }
    public void setQtde(int quantidade){
        this.qtde = quantidade;
    }

    public Long getCodigoProduto(){
        return codigoProduto;
    }
    public void setCodigoProduto(Long cod){
        this.codigoProduto = cod;
    }

    public Double getPrecoUnitario(){
        return precoUnitario;
    }
    public void setPrecoUnitario(Double preco){
        this.precoUnitario = preco;
    }

    public Double getValorTotal(){
        return valorTotal;
    }
    public void setValorTotal(Double val){
        this.valorTotal = val;
    }


    public String paraString() {
        return "ItemCompra{" +
                "qtde=" + qtde +
                ", codigoProduto=" + codigoProduto +
                ", precoUnitario=" + precoUnitario +
                ", valorTotal=" + valorTotal +
                '}';
    }

    public Produto procurarProdutoPorID(Long id) throws IOException {
        File fileProduto = new File("Produto.json");
        ArrayList<Produto> arrayProduto = new ArrayList<>();
        if (!fileProduto.createNewFile() && fileProduto.length() > 0) {
            arrayProduto.addAll(Json.readAllData(fileProduto, Produto.class));
        }

        Produto item = null;

        for (Produto p: arrayProduto) {
            if(p.getCodigo().compareTo(id) == 0){
                item = p;
            }
        }

        return item;
    }
}

这是我的 objectMapper 构建器:

public static ObjectMapper getDefaultObjectMapper(){


        ObjectMapper defaultObjectMapper = new ObjectMapper();


        defaultObjectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); // Configuração para guardar o tipo do objeto no json


        //objectMapper.addMixIn(ArrayList.class, MixinArray.class);


        return defaultObjectMapper;


    }

这是我得到的错误:

Continuo com o erro:

Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve type id 'java.util.ArrayList' as a subtype of `org.POO_AC2.dominio.compra.ItemCompra`: known type ids = [ItemCompra] (for POJO property 'itensCompra')
 at [Source: (FileInputStream); line: 1, column: 527] (through reference chain: java.util.ArrayList[0]->org.POO_AC2.dominio.compra.Compra["itensCompra"])
    at com.fasterxml.jackson.databind.exc.InvalidTypeIdException.from(InvalidTypeIdException.java:43)
    at com.fasterxml.jackson.databind.DeserializationContext.invalidTypeIdException(DeserializationContext.java:2084)
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownTypeId(DeserializationContext.java:1575)
    at com.fasterxml.jackson.databind.jsontype.impl.TypeDeserializerBase._handleUnknownTypeId(TypeDeserializerBase.java:298)
    at com.fasterxml.jackson.databind.jsontype.impl.TypeDeserializerBase._findDeserializer(TypeDeserializerBase.java:165)
    at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer._deserialize(AsArrayTypeDeserializer.java:97)
    at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer.deserializeTypedFromObject(AsArrayTypeDeserializer.java:61)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeWithType(BeanDeserializerBase.java:1296)
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:138)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:314)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:215)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:187)
    at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer._deserializeTypedForId(AsPropertyTypeDeserializer.java:170)
    at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer.deserializeTypedFromObject(AsPropertyTypeDeserializer.java:136)
    at com.fasterxml.jackson.databind.jsontype.impl.AsPropertyTypeDeserializer.deserializeTypedFromAny(AsPropertyTypeDeserializer.java:240)
    at com.fasterxml.jackson.databind.deser.std.UntypedObjectDeserializerNR.deserializeWithType(UntypedObjectDeserializerNR.java:115)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer._deserializeFromArray(CollectionDeserializer.java:361)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:244)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:28)
    at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer._deserialize(AsArrayTypeDeserializer.java:120)
    at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer.deserializeTypedFromArray(AsArrayTypeDeserializer.java:53)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserializeWithType(CollectionDeserializer.java:283)
    at com.fasterxml.jackson.databind.deser.impl.TypeWrappedDeserializer.deserialize(TypeWrappedDeserializer.java:74)
    at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:323)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4825)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3817)
    at org.POO_AC2.dominio.recursos.Json.Json.readAllData(Json.java:53)
    at org.POO_AC2.Main.atualizarPagamentoCompra(Main.java:778)
    at org.POO_AC2.Main.main(Main.java:87)

Idk我还能做什么。

我已经试过参加我的 compra 课程。

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.WRAPPER_ARRAY, property = "type")

    private ArrayList<ItemCompra> itensCompra;

但它也没有奏效。

java json 数组列表 jackson jackson-databind

评论

0赞 Ahmed Mera 11/13/2023
你能分享一下JSON的例子吗?
0赞 Vinicius Candido 11/13/2023
@AhmedMera 下面是 json:
0赞 Vinicius Candido 11/13/2023
[“java.util.ArrayList”,[{“@class”:“org.POO_AC2.dominio.compra.Compra“,”dataCompra“:”2023-11-13T00:05:46.252692800“,”valorTotal“:96.0,”cliente“:{”type“:”PF“,”id“:1,”nome“:”Vinicius“,”endereco“:{”@class“:”org.POO_AC2.dominio.cliente.Endereco“,”rua“:”Donatario“,”numero“:321,”bairro“:”santa“,”cep“:32132112,”cidade“:”salto“,”estado“:”sp“},”dataCadastro“:”2023-11-11T10:51:25.375282200“,”cpf“:”32132132112“,”qntParcelasMax“:12},”itensCompra“:[”java.util.ArrayList“,[{”@class“:”org.POO_AC2.dominio.compra.ItemCompra“,”qtde“:3,”codigoProduto“:3,”precoUnitario“:32.0,”valorTotal“:96.0}]],
0赞 Vinicius Candido 11/13/2023
“parcelasTotais”:2,“parcelasPagas”:0,“ultimoPagamento”:null,“id”:1}]]

答:

0赞 Ahmed Mera 11/13/2023 #1

我发现了问题,您必须删除此行,因为您没有在所有类中飞行的 ID(您拥有的字段,它的名称不同)。然后我试图对你的 JSON 进行脱轨,我做到了@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")

欧美:

public class Compra {
// Your code here
}

public class ItemCompra {
// Your code here
}

要测试它,请执行以下操作:

public static void main(String[] args) throws JsonProcessingException {
    String s = """
            [
               "java.util.ArrayList",
               [
                  {
                     "@class":"it.piksel.appdelivery.test.TestJson",
                     "dataCompra":"2023-11-13T00:05:46.252692800",
                     "valorTotal":96.0,
                     "cliente":{
                        "type":"PF",
                        "id":1,
                        "nome":"Vinicius",
                        "endereco":{
                           "@class":"org.POO_AC2.dominio.cliente.Endereco",
                           "rua":"Donatario",
                           "numero":321,
                           "bairro":"santa",
                           "cep":32132112,
                           "cidade":"salto",
                           "estado":"sp"
                        },
                        "dataCadastro":"2023-11-11T10:51:25.375282200",
                        "cpf":"32132132112",
                        "qntParcelasMax":12
                     },
                     "itensCompra":[
                        "java.util.ArrayList",
                        [
                           {
                              "@class":"it.piksel.appdelivery.test.ItemCompra",
                              "qtde":3,
                              "codigoProduto":3,
                              "precoUnitario":32.0,
                              "valorTotal":96.0
                           }
                        ]
                     ],
                     "parcelasTotais":2,
                     "parcelasPagas":0,
                     "ultimoPagamento":null,
                     "id":1
                  }
               ]
            ]
            """;


    ObjectMapper defaultObjectMapper = new ObjectMapper();



    defaultObjectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); 

    List<TestJson> t = defaultObjectMapper.readValue(s, new TypeReference<>() {
    });

    System.out.println(defaultObjectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(t));

}

试试吧,让我知道。

评论

0赞 Vinicius Candido 11/13/2023
您的意思是从两个类中删除@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = “type”)?好的,我会尝试的。
0赞 Ahmed Mera 11/13/2023
正确。让我知道..
0赞 Vinicius Candido 11/13/2023
我注释了两个类的行,但仍然出现相同的错误:线程“main”com.fasterxml.jackson.databind.exc.InvalidTypeIdException中的异常:无法将类型 id 'java.util.ArrayList' 解析为 : 不是 [Source: (FileInputStream); line: 1, column: 462] 的子类型(通过引用链:java.util.ArrayList[0]->org。POO_AC2.dominio.compra.Compra[“itensCompra”]).看起来 Jackson 将 arraylist 视为 ItemCompra 的子类型,但不知道为什么。org.POO_AC2.dominio.compra.ItemCompra