在同一个 JSON 中包含深层和浅层对象视图

Include both deep and shallow object views in the same JSON

给出这样的枚举:

public enum Planet{
    MERCURY ("Mercury", 0.4),
    VENUS ("Venus", 0.7),
    EARTH ("Earth", 1.0),
    MARS ("Mars", 1.5);

    private final String name;
    private final double distance;

    Planet(String name, double distance, double mass){
        this.name = name;
        this.distance = distance;
    }

    public String getName(){
        return name;
    }

    public double getDistance(){
        return distance;
    }
}

...和 ​​class 将此枚举作为 属性,如下所示:

public class Route{
    private Planet from;
    private Planet to;

    public Route (Planet from, Planet to){
        this.from = from;
        this.to = to;
    }

    public Planet getFrom(){
        return from;
    }

    public Planet getTo(){
        return to;
    }
}

使用 Jackson 将其序列化为 JSON 的正确方法是什么,以便生成的 JSON 包含深层和浅层 Planet 枚举,如下所示:

{
    "planets":{
        "MERCURY":{
            "name":"Mercury",
            "distance":"0,4"
        },
        ... 
    },
    "route":{
        "from":"EARTH",
        "to":"MARS"
    }
}

首先,为了获得深层枚举结构,我用 @JsonFormat(shape = JsonFormat.Shape.OBJECT) 对其进行了注释,但随后它也在 route 属性.

中进行了深度序列化

我该怎么做?

谢谢!

我使用了以下解决方案。

  1. 将 Planet 枚举注释如下:
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum Planet{
    /* skipped */
}

默认情况下,Jackson 将枚举序列化为字符串(常量名称),但使用此注释 Jackson 将为我们提供深层枚举结构。

  1. 带注释的 属性 吸气剂
public class Route{

    /* skipped */

    @JsonFormat(shape = JsonFormat.Shape.STRING)    
    public Planet getFrom(){/*...*/}

    @JsonFormat(shape = JsonFormat.Shape.STRING)
    public Planet getTo(){/*...*/}
}

在这里,我们将枚举序列化为对象,并要求 Jackson 简单地给我们一个枚举的常量名称。

  1. 最后但同样重要的是,将 Map<String, Planet> 添加到 Planet 枚举中:
public enum Planet {

    /*skipped*/

    private static Map<String, Planet> planetsMap;

    static {
        planetMap = new HashMap<>();
        for (Planet planet : Planet.values()) {
            planetMap.put(planet.name(), planet);
        }
    }

    public static Map<String,Planet> getPlanets(){
        return new HashMap<>(planetsMap);
    }
}

在 Planet 枚举中引入静态地图允许我们将此地图传递给 Jackson JSON 序列化程序并获得 "planets" 属性,如上文 JSON 所示,以枚举常量名称作为键。