RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1443857
Accepted
dark_buckwheat
dark_buckwheat
Asked:2022-08-29 22:19:54 +0000 UTC2022-08-29 22:19:54 +0000 UTC 2022-08-29 22:19:54 +0000 UTC

如何在json中正确序列化/反序列化具有复杂结构的类对象

  • 772

这个问题很可能已经被问过了,但是我能找到的所有东西都有一点,但仍然不合适。问题的本质:在项目中,我需要能够从文件中保存和读取有关CollectionManager存储HashSet类对象Dragon和更多变量的类对象的数据。实际上,问题在于类对象Dragon还包含其他已经属于类DragonCave和Coordinates. 我需要以某种方式保存我编写/读取的 collectionManager 包含一组龙的信息,这些龙仍然有它们的洞穴和它们的坐标。

还有一个小问题:我在集合管理器和 Dragon 本身中有类型字段java.time.LocalDate,当我尝试使用 Gson 库对它们进行序列化时,抛出异常“无法使字段私有静态最终长 java. time.LocalDate.serialVersionUID 可访问:模块 java.base 不会“打开 java.time”到未命名模块 @6d86b085”

谢谢你花时间陪我。

类和解析器代码: CollectionManager:

package Managers;

import Classes.Dragon;
import Exceptions.FieldNullException;
import Exceptions.IncorrectFieldValueException;

import java.time.LocalDate;
import java.util.HashSet;
import java.util.StringJoiner;


public class CollectionManager {
    private long currentId = 0;
    private HashSet<Dragon> collection;
    private final LocalDate initializationDate;
    private String filePath;

    public CollectionManager(HashSet<Dragon> collection, String filePath) throws IncorrectFieldValueException, FieldNullException {
        this.filePath = filePath;
        this.collection = collection;
        initializationDate = getDate();
    }

    public void setFilePath(String filePath){
        this.filePath = filePath;
    }

    public long getNewId(){
        return currentId++;
    }

    public LocalDate getDate(){
        return LocalDate.now();
    }

    public HashSet<Dragon> getCollection(){
        return collection;
    }

    public void addElement(Dragon element){
        collection.add(element);
    }

    public void removeElementById(Long id){
        collection.removeIf(d -> d.getId().equals(id));
    }

    public void clear(){
        collection.clear();
    }

    public LocalDate getInitializationDate() {
        return initializationDate;
    }

    public String toString() {
        StringJoiner stringJoiner = new StringJoiner("\n");
        if (collection.size() > 0) {
            collection.forEach((k) -> stringJoiner.add(k.toString()));
        } else {
            stringJoiner.add("The collection is empty");
        }
        return stringJoiner.toString();
    }
}

龙:

package Classes;

import Managers.CollectionManager;
import Exceptions.FieldNullException;
import Exceptions.IncorrectFieldValueException;

import java.time.LocalDate;
import java.util.Objects;

public class Dragon implements Comparable<Dragon>{
    private Long id; //Поле не может быть null, Значение поля должно быть больше 0, Значение этого поля должно быть уникальным, Значение этого поля должно генерироваться автоматически
    private String name; //Поле не может быть null, Строка не может быть пустой
    private Coordinates coordinates; //Поле не может быть null
    private java.time.LocalDate creationDate; //Поле не может быть null, Значение этого поля должно генерироваться автоматически
    private int age; //Значение поля должно быть больше 0
    private float wingspan; //Значение поля должно быть больше 0
    private Boolean speaking; //Поле не может быть null
    private Color color; //Поле не может быть null
    private DragonCave cave; //Поле не может быть null


    public Dragon(CollectionManager collectionManager, String name, Coordinates coordinates, int age,
                  float wingspan, Boolean speaking, Color color, DragonCave cave)
            throws FieldNullException, IncorrectFieldValueException {
        if (collectionManager == null) {
            throw new FieldNullException("CollectionManager");
        } else if (name == null) {
            throw new FieldNullException("name");
        } else if (coordinates == null) {
            throw new FieldNullException("coordinates");
        } else if (speaking == null) {
            throw new FieldNullException("speaking");
        } else if (color == null) {
            throw new FieldNullException("color");
        } else if (cave == null) {
            throw new FieldNullException("cave");
        }

        if (name.equals("")) {
            throw new IncorrectFieldValueException("name", name, "not null and not \"\"");
        } else if (age <= 0) {
            throw new IncorrectFieldValueException("age", String.valueOf(age), "greater than 0");
        } else if (wingspan <= 0) {
            throw new IncorrectFieldValueException("wingspan", String.valueOf(wingspan), "greater than 0");
        }

        this.id = collectionManager.getNewId();
        this.name = name;
        this.coordinates = coordinates;
        this.creationDate = collectionManager.getDate();
        this.age = age;
        this.wingspan = wingspan;
        this.speaking = speaking;
        this.color = color;
        this.cave = cave;
    }


    // гетеры
    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public Coordinates getCoordinates() {
        return coordinates;
    }

    public LocalDate getCreationDate() {
        return creationDate;
    }

    public int getAge() {
        return age;
    }

    public float getWingspan() {
        return wingspan;
    }

    public Boolean getSpeaking() {
        return speaking;
    }

    public Color getColor() {
        return color;
    }

    public DragonCave getCave() {
        return cave;
    }


    // сеттеры
    public void setId(Long id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setCoordinates(Coordinates coordinates) {
        this.coordinates = coordinates;
    }

    public void setCreationDate(LocalDate creationDate) {
        this.creationDate = creationDate;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setWingspan(float wingspan) {
        this.wingspan = wingspan;
    }

    public void setSpeaking(Boolean speaking) {
        this.speaking = speaking;
    }

    public void setColor(Color color) {
        this.color = color;
    }

    public void setCave(DragonCave cave) {
        this.cave = cave;
    }

    public int compareTo(Dragon anotherDragon){
        if (name.compareTo(anotherDragon.getName()) != 0) {
            return name.compareTo(anotherDragon.getName());
        }
        else if (Integer.valueOf(age).compareTo(anotherDragon.getAge()) != 0){
            return Integer.valueOf(age).compareTo(anotherDragon.getAge());
        }
        else{
            return Float.valueOf(wingspan).compareTo(anotherDragon.getWingspan());
        }
    }

    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Dragon dragon)) return false;
        return age == dragon.age && Float.compare(dragon.wingspan, wingspan) == 0 && id.equals(dragon.id) &&
                name.equals(dragon.name) && coordinates.equals(dragon.coordinates) &&
                creationDate.equals(dragon.creationDate) && speaking.equals(dragon.speaking) &&
                color == dragon.color && cave.equals(dragon.cave);
    }

    public int hashCode() {
        return Objects.hash(id, name, coordinates, creationDate, age, wingspan, speaking, color, cave);
    }

    public String toString() {
        return "Dragon{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", coordinates=" + coordinates +
                ", creationDate=" + creationDate +
                ", age=" + age +
                ", wingspan=" + wingspan +
                ", speaking=" + speaking +
                ", color=" + color +
                ", cave=" + cave +
                '}';
    }
}

坐标:

package Classes;

import Exceptions.IncorrectFieldValueException;

public class Coordinates {
    private long x; //Значение поля должно быть больше -846
    private double y;

    public Coordinates(long x, double y) throws IncorrectFieldValueException{
        setX(x);
        setY(y);
    }

    public double getY() {
        return y;
    }

    public void setY(double y) {
        this.y = y;
    }

    public long getX() {
        return x;
    }

    public void setX(long x) throws IncorrectFieldValueException {
        if (x < -845) throw new IncorrectFieldValueException("x", String.valueOf(x), "greater than -846");
        this.x = x;
    }

    @Override
    public String toString() {
        return "Coordinates{" +
                "x=" + x +
                ", y=" + y +
                '}';
    }
}

龙穴:

package Classes;

import java.util.Objects;

public class DragonCave {
    private int depth;

    public DragonCave(int depth){
        this.depth = depth;
    }

    public int getDepth() {
        return depth;
    }

    public void setDepth(int depth) {
        this.depth = depth;
    }

    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof DragonCave)) return false;
        DragonCave that = (DragonCave) o;
        return depth == that.depth;
    }

    public int hashCode() {
        return Objects.hash(depth);
    }

    public String toString() {
        return "DragonCave{" +
                "depth=" + depth +
                '}';
    }
}

颜色:

package Classes;

import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;

public enum Color {

    BLUE("синий"),
    YELLOW("жёлтый"),
    WHITE("белый");

    private final String colorName;

    private Color(String colorName) {
        this.colorName = colorName;
    }

    private final static Map<String, Color> colors = Arrays.stream(Color.values())
            .collect(Collectors.toMap(k->k.colorName, v->v));

    public static Color getColorByName(String colorName) {
        return colors.get(colorName);
    }

    public String toString() {
        return colorName;
    }
}

解析器:

package Managers;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashSet;
import java.util.Scanner;

import Exceptions.FieldNullException;
import Exceptions.IncorrectFieldValueException;
import com.google.gson.Gson;

public class Parser {
    private Parser() {
    }

    public static CollectionManager convertToJavaObject(File file) throws FieldNullException, IncorrectFieldValueException, FileNotFoundException {
        Gson gson = new Gson();
        // магическим образом получить строку(data) из всего этого
        Scanner scan = new Scanner(file);
        String data = scan.nextLine();
        // это просто отвратительно, но другого способа не придумал
        CollectionManager collectionManager = gson.fromJson(data, CollectionManager.class);
        collectionManager.setFilePath(file.getPath());
        return new CollectionManager(new HashSet<>(), "");
    }

    public static void convertToJSON(CollectionManager data){
        Gson gson = new Gson();
        String json = gson.toJson(data);
        System.out.println(json);
    }
}
java
  • 1 1 个回答
  • 35 Views

1 个回答

  • Voted
  1. Best Answer
    dark_buckwheat
    2022-08-31T05:08:31Z2022-08-31T05:08:31Z

    我能够自己找到解决方案。这篇文章帮助了我。我必须为每个复杂对象编写单独的序列化器和反序列化器。这是他们的代码(可能不可靠且过于复杂,但绝对有效)。

    CaveSerializer

    
    import Classes.DragonCave;
    import com.google.gson.*;
    
    import java.lang.reflect.Type;
    
    public class CaveSerializer implements JsonSerializer<DragonCave>
    {
        @Override
        public JsonElement serialize(DragonCave cave, Type typeOfSrc, JsonSerializationContext context)
        {
            JsonObject result = new JsonObject();
            result.addProperty("depth", cave.getDepth());
            return result;
        }
    }
    

    CaveDeserializer

    
    import Classes.DragonCave;
    import com.google.gson.JsonDeserializationContext;
    import com.google.gson.JsonDeserializer;
    import com.google.gson.JsonElement;
    import com.google.gson.JsonObject;
    
    import java.lang.reflect.Type;
    
    public class CaveDeserializer implements JsonDeserializer<DragonCave> {
        public DragonCave deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) {
            JsonObject jsonObject = json.getAsJsonObject();
            return new DragonCave(jsonObject.get("depth").getAsInt());
        }
    }
    

    坐标序列化器

    
    import Classes.Coordinates;
    import com.google.gson.*;
    
    import java.lang.reflect.Type;
    
    public class CoordinatesSerializer implements JsonSerializer<Coordinates>
    {
        @Override
        public JsonElement serialize(Coordinates cords, Type typeOfSrc, JsonSerializationContext context)
        {
            JsonObject result = new JsonObject();
    
            result.addProperty("x", cords.getX());
            result.addProperty("y", cords.getY());
    
            return result;
    
        }
    }
    
    

    坐标反序列化器

    package JSONstaff;
    
    import Classes.Coordinates;
    import Exceptions.IncorrectFieldValueException;
    import com.google.gson.*;
    
    import java.lang.reflect.Type;
    
    public class CoordinatesDeserializer implements JsonDeserializer<Coordinates> {
        public Coordinates deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
        {
            JsonObject jsonObject = json.getAsJsonObject();
            try {
                return new Coordinates(jsonObject.get("x").getAsLong(), jsonObject.get("y").getAsDouble());
            } catch (IncorrectFieldValueException e) {
                e.printStackTrace();
                return null;
            }
        }
    }
    
    

    DragonSerializer

    package JSONstaff;
    
    import Classes.Dragon;
    
    import com.google.gson.*;
    
    import java.lang.reflect.Type;
    
    public class DragonSerializer implements JsonSerializer<Dragon>
    {
        public JsonElement serialize(Dragon src, Type typeOfSrc, JsonSerializationContext context)
        {
            JsonObject result = new JsonObject();
    
            result.addProperty("id", src.getId());
            result.addProperty("name", src.getName());
            result.add("coordinates", context.serialize(src.getCoordinates()));
            result.addProperty("creationDate", src.getCreationDate().toString());
            result.addProperty("age", src.getAge());
            result.addProperty("wingspan", src.getWingspan());
            result.addProperty("speaking", src.getSpeaking());
            result.addProperty("color", src.getColor().toString());
            result.add("cave", context.serialize(src.getCave()));
    
            return result;
        }
    }
    
    

    DragonDeserializer

    package JSONstaff;
    
    import Classes.Color;
    import Classes.Coordinates;
    import Classes.Dragon;
    import Classes.DragonCave;
    import Exceptions.FieldNullException;
    import Exceptions.IncorrectFieldValueException;
    import com.google.gson.JsonDeserializationContext;
    import com.google.gson.JsonDeserializer;
    import com.google.gson.JsonElement;
    import com.google.gson.JsonObject;
    
    import java.lang.reflect.Type;
    
    public class DragonDeserializer implements JsonDeserializer<Dragon> {
        public Dragon deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context){
            JsonObject jsonObject = json.getAsJsonObject();
            Dragon dragon = null;
            try {
                dragon = new Dragon(jsonObject.get("name").getAsString(),
                        context.deserialize(jsonObject.get("coordinates"), Coordinates.class),
                        jsonObject.get("age").getAsInt(),
                        jsonObject.get("wingspan").getAsFloat(),
                        jsonObject.get("speaking").getAsBoolean(),
                        Color.getColorByName(jsonObject.get("color").getAsString()),
                        context.deserialize(jsonObject.get("cave"), DragonCave.class));
            } catch (FieldNullException | IncorrectFieldValueException e) {
                e.printStackTrace();
            }
            assert dragon != null;
            dragon.setId(jsonObject.get("id").getAsLong());
            return dragon;
        }
    }
    
    

    CollectionSerializer

    package JSONstaff;
    
    import Classes.Dragon;
    import Managers.CollectionManager;
    import com.google.gson.*;
    
    import java.lang.reflect.Type;
    
    public class CollectionSerializer implements JsonSerializer<CollectionManager> {
        public JsonElement serialize(CollectionManager collectionManager, Type typeOfSrc, JsonSerializationContext context){
            JsonObject result = new JsonObject();
            JsonArray col = new JsonArray();
    
            for(Dragon dragon : collectionManager.getCollection()) {
                col.add(context.serialize(dragon));
            }
            result.addProperty("currentId", collectionManager.getId());
            result.add("collection", col);
            //result.addProperty("filePath", collectionManager.getFilePath());
            //не думаю, что файл должен хранить в себе путь к себе же
            result.addProperty("initializationDate", collectionManager.getInitializationDate().toString());
            return result;
        }
    }
    

    CollectionDeserializer

    package JSONstaff;
    
    import Classes.Dragon;
    import Exceptions.FieldNullException;
    import Exceptions.IncorrectFieldValueException;
    import Managers.CollectionManager;
    import com.google.gson.*;
    
    import java.lang.reflect.Type;
    import java.util.HashSet;
    
    public class CollectionDeserializer implements JsonDeserializer<CollectionManager> {
        public CollectionManager deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
        {
            JsonObject jsonObject = json.getAsJsonObject();
            HashSet<Dragon> collection = new HashSet();
            for(JsonElement dragon : jsonObject.get("collection").getAsJsonArray()) {
                collection.add(context.deserialize(dragon, Dragon.class));
            }
            try {
                return new CollectionManager(collection, jsonObject.get("filePath").getAsString());
            } catch (IncorrectFieldValueException | FieldNullException e) {
                e.printStackTrace();
                return null;
            }
        }
    }
    

    Переделанный Parser

    package Managers;
    
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.util.*;
    
    import Classes.Coordinates;
    import Classes.Dragon;
    import Classes.DragonCave;
    import JSONstaff.*;
    import com.google.gson.Gson;
    import com.google.gson.GsonBuilder;
    
    public class Parser {
        private Parser() {
        }
    
        public static CollectionManager convertToJavaObject(File file) throws FileNotFoundException{
            Scanner scan = new Scanner(file);
            StringJoiner data = new StringJoiner("");
            while (scan.hasNextLine()){
                data.add(scan.nextLine());
            }
            Gson gson = new GsonBuilder()
                    .registerTypeAdapter(CollectionManager.class, new CollectionDeserializer())
                    .registerTypeAdapter(Dragon.class, new DragonDeserializer())
                    .registerTypeAdapter(Coordinates.class, new CoordinatesDeserializer())
                    .registerTypeAdapter(DragonCave.class, new CaveDeserializer())
                    .create();
            return gson.fromJson(data.toString(), CollectionManager.class);
        }
    
        public static void convertToJSON(CollectionManager data){
            Gson gson = new GsonBuilder()
                    .setPrettyPrinting()
                    .registerTypeAdapter(CollectionManager.class, new CollectionSerializer())
                    .registerTypeAdapter(Dragon.class, new DragonSerializer())
                    .registerTypeAdapter(Coordinates.class, new CoordinatesSerializer())
                    .registerTypeAdapter(DragonCave.class, new CaveSerializer())
                    .create();
        }
    }
    
    • 0

相关问题

  • wpcap 找不到指定的模块

  • 如何以编程方式从桌面应用程序打开 HTML 页面?

  • Android Studio 中的 R.java 文件在哪里?

  • HashMap 初始化

  • 如何使用 lambda 表达式通过增加与原点的距离来对点进行排序?

  • 最大化窗口时如何调整元素大小?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5