在同一个 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
属性.
中进行了深度序列化
我该怎么做?
谢谢!
我使用了以下解决方案。
- 将 Planet 枚举注释如下:
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum Planet{
/* skipped */
}
默认情况下,Jackson 将枚举序列化为字符串(常量名称),但使用此注释 Jackson 将为我们提供深层枚举结构。
- 带注释的 属性 吸气剂
public class Route{
/* skipped */
@JsonFormat(shape = JsonFormat.Shape.STRING)
public Planet getFrom(){/*...*/}
@JsonFormat(shape = JsonFormat.Shape.STRING)
public Planet getTo(){/*...*/}
}
在这里,我们将枚举序列化为对象,并要求 Jackson 简单地给我们一个枚举的常量名称。
- 最后但同样重要的是,将
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 所示,以枚举常量名称作为键。
给出这样的枚举:
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
属性.
我该怎么做?
谢谢!
我使用了以下解决方案。
- 将 Planet 枚举注释如下:
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum Planet{
/* skipped */
}
默认情况下,Jackson 将枚举序列化为字符串(常量名称),但使用此注释 Jackson 将为我们提供深层枚举结构。
- 带注释的 属性 吸气剂
public class Route{
/* skipped */
@JsonFormat(shape = JsonFormat.Shape.STRING)
public Planet getFrom(){/*...*/}
@JsonFormat(shape = JsonFormat.Shape.STRING)
public Planet getTo(){/*...*/}
}
在这里,我们将枚举序列化为对象,并要求 Jackson 简单地给我们一个枚举的常量名称。
- 最后但同样重要的是,将
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 所示,以枚举常量名称作为键。