【问题标题】:Serialization/Deserialization JSON Jackson HashMap JAVA序列化/反序列化 JSON Jackson HashMap JAVA
【发布时间】:2023-03-04 06:04:02
【问题描述】:

我有一个简单的问题,但我自己找不到解决方案。

我需要序列化两张地图。一个以 Object 为键,以 Integer 为值。另一个 One 具有类似的属性,但 key-object 包含一个列表。

这是我的模型。

详情

package Model;


/**
 * Created by kh0ma on 01.11.16.
 */
public class Detail {
    private String name;

    public Detail() {
    }

    public Detail(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Detail{" +
                "name='" + name + '\'' +
                '}';
    }
}

机制

package Model;



import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by kh0ma on 01.11.16.
 */
public class Mechanism {
    private String name;
    private List<Detail> details;

    public Mechanism(String name) {
        this.name = name;
        this.details = new ArrayList<Detail>();
    }

    public String getName() {
        return name;
    }

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


    public List<Detail> getDetails() {
        return details;
    }

    public void setDetails(List<Detail> details) {
        this.details = details;
    }

    @Override
    public String toString() {
        return "Mechanism{" +
                "name='" + name + '\'' +
                ", details=" + details +
                '}';
    }
}

然后我通过另一个类在地图中提取数据。

拉数据

package PullData;

import Model.Detail;
import Model.Mechanism;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by kh0ma on 01.11.16.
 */
public class PullData {
    public static Map<Detail,Integer> DETAILS = new HashMap<Detail, Integer>();

    public static Map<Mechanism,Integer> MECHANISMS = new HashMap<Mechanism, Integer>();


    private static Detail detail1 = new Detail("Wheel");
    private static Detail detail2 = new Detail("Frame");
    private static Detail detail3 = new Detail("Seat");
    private static Detail detail4 = new Detail("Engine");
    private static Detail detail5 = new Detail("Headlight");

    public static void pullDetails()
    {

        DETAILS.put(detail1,6);
        DETAILS.put(detail2,2);
        DETAILS.put(detail3,5);
        DETAILS.put(detail4,1);
        DETAILS.put(detail5,2);
    }

    public static void pullMechanisms()
    {
        Mechanism car = new Mechanism("Car");

        car.getDetails().add(detail1);
        car.getDetails().add(detail2);
        car.getDetails().add(detail3);
        car.getDetails().add(detail4);
        car.getDetails().add(detail5);

        Mechanism bicycle = new Mechanism("Bicycle");

        bicycle.getDetails().add(detail1);
        bicycle.getDetails().add(detail2);

        MECHANISMS.put(car,1);
        MECHANISMS.put(bicycle,1);
    }
}

比我尝试在 main 方法中序列化和反序列化地图。

TestJSON

package TestJSON;

import Model.Detail;
import Model.Mechanism;
import PullData.PullData;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.MapType;


import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by kh0ma on 01.11.16.
 */
public class TestJSON {
public static void main(String[] args) {
    PullData.pullDetails();
    PullData.pullMechanisms();

    System.out.println("=+=+=+=BEFORE JSON SERIALISATION=+=+=+=");

    System.out.println("-=-=-=-=-=Before changes=-=-=-=-=-=-");

    PullData.DETAILS.forEach((k, v) -> System.out.println(k));
    PullData.MECHANISMS.forEach((k, v) -> System.out.println(k));

    System.out.println("-=-=-=-=-=After changes=-=-=-=-=-=-");

    PullData.MECHANISMS.forEach((k, v) -> {
        if (k.getName().equals("Bicycle")) k.getDetails()
                .forEach((detail -> detail.setName(detail.getName() + "FirstChanges")));
    });

    PullData.DETAILS.forEach((k, v) -> System.out.println(k));
    PullData.MECHANISMS.forEach((k, v) -> System.out.println(k));

    System.out.println("=+=+=+=JSON Print=+=+=+=");

    ObjectMapper objectMapper = new ObjectMapper();

    File jsonFileDetails = new File("src/main/resources/json/jsonDetails.txt");
    File jsonFileMechanisms = new File("src/main/resources/json/jsonMechanisms.txt");

    try {
        objectMapper.writerWithDefaultPrettyPrinter().writeValue(jsonFileDetails, PullData.DETAILS);
        objectMapper.writerWithDefaultPrettyPrinter().writeValue(jsonFileMechanisms, PullData.MECHANISMS);
    } catch (JsonGenerationException e) {
        e.printStackTrace();
    } catch (JsonMappingException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    System.out.println("=+=+=+=AFTER JSON SERIALISATION=+=+=+=");

    System.out.println("-=-=-=-=-=Before changes=-=-=-=-=-=-");

    ObjectMapper mapper = new ObjectMapper();

    MapType mapType = mapper.getTypeFactory().constructMapType(HashMap.class, Mechanism.class, Integer.class);

    Map<Detail, Integer> detailesAfterJson = new HashMap<Detail, Integer>();
    Map<Mechanism, Integer> mechanismsAfterJson = new HashMap<Mechanism, Integer>();

    try {
        detailesAfterJson = mapper.readValue(jsonFileDetails, new TypeReference<HashMap<Detail, Integer>>() {});
        mechanismsAfterJson = mapper.readValue(jsonFileMechanisms, new TypeReference<Map<Mechanism, Integer>>() {});
    } catch (JsonGenerationException e) {
        e.printStackTrace();
    } catch (JsonMappingException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    detailesAfterJson.forEach((k, v) -> System.out.println(k));
    mechanismsAfterJson.forEach((k, v) -> System.out.println(k));
    }
}

第一张地图是这样序列化的。

jsonDetails.txt

{
  "Detail{name='WheelFirstChanges'}" : 6,
  "Detail{name='FrameFirstChanges'}" : 2,
  "Detail{name='Seat'}" : 5,
  "Detail{name='Engine'}" : 1,
  "Detail{name='Headlight'}" : 2
}

还有一个这样的。

jsonMechanisms.txt

{
  "Mechanism{name='Car', details=[Detail{name='WheelFirstChanges'}, Detail{name='FrameFirstChanges'}, Detail{name='Seat'}, Detail{name='Engine'}, Detail{name='Headlight'}]}" : 1,
  "Mechanism{name='Bicycle', details=[Detail{name='WheelFirstChanges'}, Detail{name='FrameFirstChanges'}]}" : 1
}

在 java 控制台中我有这个输出。

控制台输出

/usr/lib/jvm/jdk1.8.0_102/bin/java -Didea.launcher.port=7544 -Didea.launcher.bin.path=/home/kh0ma/idea-IU-162.1121.32/bin -Dfile.encoding=UTF-8 -classpath "/usr/lib/jvm/jdk1.8.0_102/jre/lib/charsets.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/deploy.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/ext/cldrdata.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/ext/dnsns.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/ext/jaccess.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/ext/jfxrt.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/ext/localedata.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/ext/nashorn.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/ext/sunec.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/ext/sunjce_provider.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/ext/sunpkcs11.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/ext/zipfs.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/javaws.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/jce.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/jfr.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/jfxswt.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/jsse.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/management-agent.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/plugin.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/resources.jar:/usr/lib/jvm/jdk1.8.0_102/jre/lib/rt.jar:/home/kh0ma/Dropbox/JavaStuding/JavaRush/JavaRushHomeWork/Test JSON for ANTONIOPRIME/target/classes:/home/kh0ma/Dropbox/JavaStuding/JavaRush/JavaRushHomeWork/Test JSON for ANTONIOPRIME/lib/gson-2.7.jar:/home/kh0ma/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.2.3/jackson-databind-2.2.3.jar:/home/kh0ma/.m2/repository/com/fasterxml/jackson/core/jackson-annotations/2.2.3/jackson-annotations-2.2.3.jar:/home/kh0ma/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.2.3/jackson-core-2.2.3.jar:/home/kh0ma/idea-IU-162.1121.32/lib/idea_rt.jar" com.intellij.rt.execution.application.AppMain TestJSON.TestJSON
=+=+=+=BEFORE JSON SERIALISATION=+=+=+=
-=-=-=-=-=Before changes=-=-=-=-=-=-
Detail{name='Wheel'}
Detail{name='Frame'}
Detail{name='Seat'}
Detail{name='Engine'}
Detail{name='Headlight'}
Mechanism{name='Car', details=[Detail{name='Wheel'}, Detail{name='Frame'}, Detail{name='Seat'}, Detail{name='Engine'}, Detail{name='Headlight'}]}
Mechanism{name='Bicycle', details=[Detail{name='Wheel'}, Detail{name='Frame'}]}
-=-=-=-=-=After changes=-=-=-=-=-=-
Detail{name='WheelFirstChanges'}
Detail{name='FrameFirstChanges'}
Detail{name='Seat'}
Detail{name='Engine'}
Detail{name='Headlight'}
Mechanism{name='Car', details=[Detail{name='WheelFirstChanges'}, Detail{name='FrameFirstChanges'}, Detail{name='Seat'}, Detail{name='Engine'}, Detail{name='Headlight'}]}
Mechanism{name='Bicycle', details=[Detail{name='WheelFirstChanges'}, Detail{name='FrameFirstChanges'}]}
=+=+=+=JSON Print=+=+=+=
=+=+=+=AFTER JSON SERIALISATION=+=+=+=
-=-=-=-=-=Before changes=-=-=-=-=-=-
Detail{name='Detail{name='Engine'}'}
Detail{name='Detail{name='Seat'}'}
Detail{name='Detail{name='Headlight'}'}
Detail{name='Detail{name='WheelFirstChanges'}'}
Detail{name='Detail{name='FrameFirstChanges'}'}
Mechanism{name='Mechanism{name='Bicycle', details=[Detail{name='WheelFirstChanges'}, Detail{name='FrameFirstChanges'}]}', details=[]}
Mechanism{name='Mechanism{name='Car', details=[Detail{name='WheelFirstChanges'}, Detail{name='FrameFirstChanges'}, Detail{name='Seat'}, Detail{name='Engine'}, Detail{name='Headlight'}]}', details=[]}

Process finished with exit code 0

你可以看到之前和之后的地图有差异,但我需要完全相同的地图。

你能建议我解决办法吗?

我将类下载到 GitHub 存储库中。

JSON_TEST

感谢您的回答。

【问题讨论】:

  • “key-object 包含一个列表”JSON 键必须是字符串。

标签: java json dictionary serialization jackson


【解决方案1】:

在 JSON 中,键必须是字符串。您的实现使用DetailMechanismtoString 方法作为键。由于这些方法返回不同的字符串,因此 JSON 键会有所不同。

如果你想序列化为 JSON,我建议不要使用字符串以外的任何东西作为映射键。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-28
    • 2023-03-11
    • 1970-01-01
    • 2020-07-07
    • 2011-08-26
    • 1970-01-01
    • 2014-08-02
    相关资源
    最近更新 更多