json 使用Jackson序列化/重新序列化BufferedImage时出错

slmsl1lt  于 2023-10-21  发布在  其他
关注(0)|答案(1)|浏览(143)

我遇到的问题是下面的一个。我试图在一个JSON文件中处理我的游戏的所有敌人,当我试图加载它们时,我从Buffered Image类中得到一个错误。我可以或多或少地理解这是因为序列化和非序列化,但我不能设法找出如何修复它,因为这是我第一次在Java中使用Jackson。
我尝试了下面的代码,我希望它像普通的Jackson构造函数加载器一样工作。

private static MonsterManager instance;
    private ArrayList<shadowStandar> monsters;

    private MonsterManager() {
        loadMonstersFromFile("res/Jsons/monsters.json"); // Ajusta la ruta según la ubicación de tu archivo JSON
    }

    public static MonsterManager getInstance() {
        if (instance == null) {
            instance = new MonsterManager();
        }
        return instance;
    }

    private void loadMonstersFromFile(String filePath) {
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            monsters = objectMapper.readValue(new File(filePath), new TypeReference<ArrayList<shadowStandar>>() {});
        } catch (IOException e) {
            e.printStackTrace();
            // Manejar excepciones apropiadamente
        }
    }

    public ArrayList<shadowStandar> getMonsters() {
        return monsters;
    }
}

怪物等级:

public class shadowStandar extends Entity {

    BufferedImage walkDown3,walkDown4,walkUp3,walkUp4,walkLeft3,walkLeft4,walkRight3,walkRight4;

    public int xpGiven;
    private String attackType;
    public BufferedImage combatImage;

    public shadowStandar(GamePanel gp) {
        super(gp);
    }

    @JsonCreator
    public shadowStandar(
            @JsonProperty("gp") GamePanel gp,
            @JsonProperty("name") String name,
            @JsonProperty("health") int health,
            @JsonProperty("str") int str,
            @JsonProperty("agi") int agi,
            @JsonProperty("mag") int mag,
            @JsonProperty("vit") int vit,
            @JsonProperty("xpGiven") int xpGiven,
            @JsonProperty("attackType") String attackType,
            @JsonProperty("combatImagePath") String combatImagePath,
            @JsonProperty("weaknesses") String[] weaknesses,
            @JsonProperty("resistances") String[] resistances,
            @JsonProperty("nulls") String[] nulls,
            @JsonProperty("repells") String[] repells
    ) {
        super(gp);
        type = 2;
        this.name = name;
        this.stats.hp = health;
        this.stats.maxHp = this.stats.hp;
        this.stats.str = str;
        this.stats.agi = agi;
        this.stats.mag = mag;
        this.stats.vit = vit;
        this.xpGiven = xpGiven;
        this.attackType = attackType;
        speed = 1;
        loadCombatImage(combatImagePath); // Cargar la imagen de combate específica
        getImage(); // Cargar las imágenes del mundo

        this.weaknesses = weaknesses;
        this.resistances = resistances;
        this.nulls = nulls;
        this.repells = repells;
    }


    public String getAttackType(){
        return attackType;
    }

    public int getPhysAttack(int playerEndurance,int attackerStat){
        return 5*(int)(Math.sqrt(((double) attackerStat/playerEndurance)*randomFactor()));
    }

    public void loadCombatImage(String combatImagePath){
        combatImage = setUp(combatImagePath);
    }

我得到以下错误:

com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Invalid type definition for type `java.awt.image.BufferedImage`: Failed to call `setAccess()` on Field 'colorModel' (of class `java.awt.image.BufferedImage`) due to `java.lang.reflect.InaccessibleObjectException`, problem: Unable to make field private java.awt.image.ColorModel java.awt.image.BufferedImage.colorModel accessible: module java.desktop does not "opens java.awt.image" to unnamed module @385c9627
 at [Source: (File); line: 1, column: 1]
    at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:62)
    at com.fasterxml.jackson.databind.DeserializationContext.reportBadTypeDefinition(DeserializationContext.java:1893)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBuilder._handleBadAccess(BeanDeserializerBuilder.java:620)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBuilder._fixAccess(BeanDeserializerBuilder.java:537)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBuilder.build(BeanDeserializerBuilder.java:384)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:295)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:151)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:415)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:350)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
    at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
    at com.fasterxml.jackson.databind.DeserializationContext.findNonContextualValueDeserializer(DeserializationContext.java:644)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.resolve(BeanDeserializerBase.java:539)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:294)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
    at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
    at com.fasterxml.jackson.databind.DeserializationContext.findContextualValueDeserializer(DeserializationContext.java:621)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.createContextual(CollectionDeserializer.java:188)
    at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.createContextual(CollectionDeserializer.java:28)
    at com.fasterxml.jackson.databind.DeserializationContext.handleSecondaryContextualization(DeserializationContext.java:867)
    at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:659)
    at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:4956)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4826)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3657)
    at monster.MonsterManager.loadMonstersFromFile(MonsterManager.java:28)
    at monster.MonsterManager.<init>(MonsterManager.java:15)
    at monster.MonsterManager.getInstance(MonsterManager.java:20)
    at main.GamePanel.<init>(GamePanel.java:51)
    at main.Main.main(Main.java:14)
Caused by: java.lang.IllegalArgumentException: Failed to call `setAccess()` on Field 'colorModel' (of class `java.awt.image.BufferedImage`) due to `java.lang.reflect.InaccessibleObjectException`, problem: Unable to make field private java.awt.image.ColorModel java.awt.image.BufferedImage.colorModel accessible: module java.desktop does not "opens java.awt.image" to unnamed module @385c9627
    at com.fasterxml.jackson.databind.util.ClassUtil.checkAndFixAccess(ClassUtil.java:1008)
    at com.fasterxml.jackson.databind.deser.impl.FieldProperty.fixAccess(FieldProperty.java:104)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBuilder._fixAccess(BeanDeserializerBuilder.java:535)
    ... 26 more
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make field private java.awt.image.ColorModel java.awt.image.BufferedImage.colorModel accessible: module java.desktop does not "opens java.awt.image" to unnamed module @385c9627
    at java.base/java.lang.reflect.AccessibleObject.throwInaccessibleObjectException(AccessibleObject.java:387)
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:363)
    at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:311)
    at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:181)
    at java.base/java.lang.reflect.Field.setAccessible(Field.java:175)
    at com.fasterxml.jackson.databind.util.ClassUtil.checkAndFixAccess(ClassUtil.java:995)
    ... 28 more
ggazkfy8

ggazkfy81#

最后,经过大量的时间,我找到了一个替代解决方案,如果有人感兴趣,我在这里留下我的解决方案:
我创建了一个新的Class,其中只有我需要输入的JSON参数,如stats,combatImagePath和String Arrays。
我将monsterManager改为monsterStatManager,最后在monster的构造函数中添加了一个monsterStat类型的参数,并正常分配它们。

public shadowStandar(GamePanel gp,monsterData data) {
        super(gp);
        this.name = data.name;
        this.stats.hp = data.hp;
        this.stats.maxHp = this.stats.hp;
        this.stats.str = data.str;
        this.stats.agi = data.agi;
        this.stats.mag = data.mag;
        this.stats.vit = data.vit;
        this.xpGiven = data.xpGiven;
        this.attackType = data.attackType;
        this.combatImagePath = data.combatImagePath;
        this.resistances = data.resistances;
        this.weaknesses = data.weaknesses;
        this.nulls = data.nulls;
        this.repells = data.repells;
        this.type = 2;
        speed = 1;
        getImage();
    }

Json类的monsterData:

// Constructor predeterminado sin argumentos
    public monsterData() {
    }

    // Constructor con argumentos anotado con @JsonCreator
    @JsonCreator
    public monsterData(
            @JsonProperty("name") String name,
            @JsonProperty("health") int health,
            @JsonProperty("str") int str,
            @JsonProperty("agi") int agi,
            @JsonProperty("mag") int mag,
            @JsonProperty("vit") int vit,
            @JsonProperty("xpGiven") int xpGiven,
            @JsonProperty("attackType") String attackType,
            @JsonProperty("combatImagePath") String combatImagePath,
            @JsonProperty("weaknesses") String[] weaknesses,
            @JsonProperty("resistances") String[] resistances,
            @JsonProperty("nulls") String[] nulls,
            @JsonProperty("repells") String[] repells
    ) {
        this.name = name;
        this.hp = health;
        this.maxHp = this.hp;
        this.str = str;
        this.agi = agi;
        this.mag = mag;
        this.vit = vit;
        this.xpGiven = xpGiven;
        this.attackType = attackType;
        this.combatImagePath = combatImagePath;

        this.weaknesses = weaknesses;
        this.resistances = resistances;
        this.nulls = nulls;
        this.repells = repells;
    }
}

相关问题