如何使用 JSON 解析接口对象矩阵?

问题描述 投票:0回答:1

我有一个 Item 接口,用于创建和存储游戏物品。这些物品以矩阵的形式存储在玩家的库存中(IItem[][]库存)。当尝试实现读取和写入功能(将对象转换为字符串并进行转换)时,出现错误。如果我创建一个清单作为这些对象的数组,那么 JSON 在数据类型中会混淆(错误代码如下),我尝试仅从 1 个特定对象创建相同的矩阵,而不使用接口,一切正常,但这不是我需要的。我可以断定问题出在注释中。

错误代码: 线程“main”中出现异常 com.fasterxml.jackson.databind.exc.InvalidTypeIdException:无法解析类型 id 'IItem;'作为

items.IItem[]
的子类型:已知类型 ids = [钻石、草、剑](对于 POJO 属性“库存”)

主要

import items.Grass;
import items.IItem;

import java.io.IOException;

public class Main {

    public static void main(String[] args) throws IOException {
        Player player = new Player(new IItem[][]{{new Grass(5, 2)}},12,20);

        player.print();

        System.out.println();

        String data = player.write();
        System.out.println(data);

        System.out.println();

        Player player2 = Player.read(data);
        player2.print();
    }
}

玩家

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.ObjectMapper;
import items.Diamond;
import items.Grass;
import items.IItem;
import items.Sword;

import java.io.IOException;

public class Player {
    @JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.PROPERTY,
        property = "type"
    )
    @JsonSubTypes({
        @JsonSubTypes.Type(value = Grass.class, name = "Grass"),
        @JsonSubTypes.Type(value = Sword.class, name = "Sword"),
        @JsonSubTypes.Type(value = Diamond.class, name = "Diamond")
    })

    private IItem[][] inventory;
    private int health;
    private int maxHealth;

    public Player() {
    }

    @JsonCreator
    public Player(
            @JsonProperty("inventory") IItem[][] inventory,
            @JsonProperty("health") int health,
            @JsonProperty("maxHealth") int maxHealth) {
        this.inventory = inventory;
        this.health = health;
        this.maxHealth = maxHealth;
    }

    public void print() {
        System.out.println("Player=h" + health + ",m" + maxHealth);
        System.out.println("Inventory has:");
        for (int i = 0; i < inventory.length; i++) {
            for (int j = 0; j < inventory[i].length; j++) {
                if (inventory[i][j] != null) {
                    System.out.print(" - ");
                    inventory[i][j].print();
                }
            }
        }
    }

    public String write() throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        return mapper.writeValueAsString(this);
    }

    public static Player read(String data) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        return mapper.readValue(data, Player.class);
    }

    public IItem[][] getInventory() {
        return inventory;
    }

    public void setInventory(IItem[][] inventory) {
        this.inventory = inventory;
    }

    public int getHealth() {
        return health;
    }

    public void setHealth(int health) {
        this.health = health;
    }

    public int getMaxHealth() {
        return maxHealth;
    }

    public void setMaxHealth(int maxHealth) {
        this.maxHealth = maxHealth;
    }
}   

物品接口(IItem)

package items;

public interface IItem {
    void print ();
}

package items;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public class Grass implements IItem {
    public String name = "grass block";
    public int count;
    public int weight;

    @JsonCreator
    public Grass(@JsonProperty("count") int count, @JsonProperty("weight") int weight) {
        this.count = count;
        this.weight = weight;
    }

    @Override
    public void print() {
        System.out.println(name + "=c:" + count + ",w:" + weight);
    }

    public String getName() {
        return name;
    }

    public int getCount() {
        return count;
    }

    public int getWeight() {
        return weight;
    }
}

package items;

import com.fasterxml.jackson.annotation.JsonProperty;

public class Sword implements IItem{
    public String name = "sword";
    public int count, damage;

    public Sword (@JsonProperty("count")int count,@JsonProperty("damage") int damage) {
        this.count=count;
        this.damage=damage;
    }

    @Override
    public void print() {
        System.out.println(name+"=c:"+count+",d:"+damage);
    }

    public String getName() {
        return name;
    }

    public int getCount() {
        return count;
    }

    public int getDamage() {
        return damage;
    }
}

钻石

package items;

import com.fasterxml.jackson.annotation.JsonProperty;

public class Diamond implements IItem{
    public String name = "sword";
    public int count;

    public Diamond(@JsonProperty("count")int count) {
        this.count=count;
    }

    @Override
    public void print() {
        System.out.println(name+"=c:"+count);
    }

    public String getName() {
        return name;
    }

    public int getCount() {
        return count;
    }
}

这是一个测试项目

我尝试进行注释,但它们仅在 1 个对象的情况下有帮助,并且 对象的规则矩阵(IItem[] inventory)。

java json parsing jackson
1个回答
0
投票

我通过将注释从 Player 移动到界面(IItem)来修复它

已编辑项目

package items;

import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.PROPERTY,
        property = "type"
)
@JsonSubTypes({
        @JsonSubTypes.Type(value = Diamond.class, name = "Diamond"),
        @JsonSubTypes.Type(value = Grass.class, name = "Grass"),
        @JsonSubTypes.Type(value = Sword.class, name = "Sword")
})

public interface IItem {
    void print ();
}

已编辑的玩家

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import items.IItem;

import java.io.IOException;

public class Player {
    private IItem[][] inventory;
    private int health;
    private int maxHealth;

    public Player() {
    }

    @JsonCreator
    public Player(
            @JsonProperty("inventory") IItem[][] inventory,
            @JsonProperty("health") int health,
            @JsonProperty("maxHealth") int maxHealth) {
        this.inventory = inventory;
        this.health = health;
        this.maxHealth = maxHealth;
    }

    public void print() {
        System.out.println("Player=h" + health + ",m" + maxHealth);
        System.out.println("Inventory has:");
        for (int i = 0; i < inventory.length; i++) {
            for (int j = 0; j < inventory[i].length; j++) {
                if (inventory[i][j] != null) {
                    System.out.print(" - ");
                    inventory[i][j].print();
                }
            }
        }
    }

    public static String write(Player player) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        return mapper.writeValueAsString(player);
    }

    public static Player read(String data) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        return mapper.readValue(data, Player.class);
    }

    public IItem[][] getInventory() {
        return inventory;
    }

    public void setInventory(IItem[][] inventory) {
        this.inventory = inventory;
    }

    public int getHealth() {
        return health;
    }

    public void setHealth(int health) {
        this.health = health;
    }

    public int getMaxHealth() {
        return maxHealth;
    }

    public void setMaxHealth(int maxHealth) {
        this.maxHealth = maxHealth;
    }
}

控制台结果:

Player=h12,m20
Inventory has:
        - grass block=c:5,w:2
        - sword=c:1,d:12
        - sword=c:8

        {"inventory":[[{"type":"Grass","count":5,"weight":2,"name":"grass block"}],[{"type":"Sword","count":1,"damage":12,"name":"sword"}],[{"type":"Diamond","count":8,"name":"sword"}]],"health":12,"maxHealth":20}

Player=h12,m20
Inventory has:
        - grass block=c:5,w:2
        - sword=c:1,d:12
        - sword=c:8
© www.soinside.com 2019 - 2024. All rights reserved.