【问题标题】:binding a child object from JSON to parent attribute java将子对象从 JSON 绑定到父属性 java
【发布时间】:2022-01-15 23:37:24
【问题描述】:

我有一个名为Component 的类,其中包含一些属性,包括Device 类的对象,它是某些类的基类,例如ResistanceM1,我必须读取组件的JSON 文件并检查设备的类型ResistanceM1 然后将其映射到正确的类我尝试使用 JSON 注释但我仍然收到错误!

这是我的课程 组件类:

public class Component {
private String type;
private String id;


@JsonProperty
private Device device;
@JsonProperty("netlist")
private HashMap<String,String> netlist;

public Component() {
}

public Component(String type, String id, Device device, HashMap<String, String> netList) {
    this.type = type;
    this.id = id;
    this.device = device;
    this.netlist = netList;
}

public String getType() {
    return type;
}

public void setType(String type) {
    this.type = type;
}

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public Device getDevice() {
    return device;
}

public void setDevice(Device device) {
    this.device = device;
}
public HashMap<String, String> getNetlist() {
    return netlist;
}

public void setNetlist(HashMap<String, String> netlist) {
    this.netlist = netlist;
}

@Override
public String toString() {
    return "type='" + type + '\'' +
            ", id='" + id + '\'' +
            ", "+device.toString()+
            ", netList=" + netlist ;
}
}

设备类:

public abstract class Device {
@JsonProperty("default")
protected int defaultValue;
protected int min;
protected int max;

public Device() {
}

public Device(int defaultValue, int min, int max) {
    this.defaultValue = defaultValue;
    this.min = min;
    this.max = max;
}

public int getDefaultValue() {
    return defaultValue;
}

public void setDefaultValue(int defaultValue) {
    this.defaultValue = defaultValue;
}

public int getMin() {
    return min;
}

public void setMin(int min) {
    this.min = min;
}

public int getMax() {
    return max;
}

public void setMax(int max) {
    this.max = max;
}


}

阻力:

    @JsonTypeName("resistance")
public class Resistance extends Device {
    public Resistance() {
    }
@Override
public String toString() {
    return "resistance{" +
            "default=" + defaultValue +
            ", min=" + min +
            ", max=" + max +
            '}';
}
}

M1 类:

@JsonTypeName(value = "m(1)")
public class M1 extends Device {
    @Override
    public String toString() {
        return "m(1){" +
                "default=" + defaultValue +
                ", min=" + min +
                ", max=" + max +
                '}';
    }
}

这是一个简单的 JSON 文件:

"components": [
  {
    "type": "resistor",
    "id": "res1",
    "resistance": {
      "default": 100,
      "min": 10,
      "max": 1000
    },
    "netlist": {
      "t1": "vdd",
      "t2": "n1"
    }
  },
  {
    "type": "nmos",
    "id": "m1",
    "m(l)": {
      "deafult": 1.5,
      "min": 1,
      "max": 2
    },
    "netlist": {
      "drain": "n1",
      "gate": "vin",
      "source": "vss"
    }
  }
]

提前致谢

【问题讨论】:

    标签: java json spring-boot binding jackson


    【解决方案1】:

    @JsonTypeName 并没有按照你的想法去做。在其reference documentation 中,您可以阅读:

    注解用于绑定被注解的类所具有的逻辑名。与 JsonTypeInfo(特别是其 JsonTypeInfo.use() 属性)一起使用,以建立类型名称和类型之间的关系。

    这意味着您在 Device@JsonTypeInfo@JsonSubTypes)中缺少关键注释,因此 Jackson 知道如何读取您提供的 JSON:

    @JsonTypeInfo(
      use = JsonTypeInfo.Id.NAME, 
      include = JsonTypeInfo.As.PROPERTY, 
      property = "type")
    @JsonSubTypes({ 
      @Type(value = Resistance.class, name = "resistance"), 
      @Type(value = M1.class, name = "m1") 
    })
    public abstract class Device {
        (...)
    }
    

    有了这个你可以摆脱ResistanceM1中的@JsonTypeName

    但是,这还不够。您还需要更改您的 JSON 以匹配 Component 属性(resistancem(1) 必须重命名为 device)并且您还需要将 type 添加到此 device 属性以匹配 @JsonTypeInfo@JsonSubTypes

    "components": [
      {
        "type": "resistor",
        "id": "res1",
        "device": {
          "type": "resistance",
          "default": 100,
          "min": 10,
          "max": 1000
        },
        "netlist": {
          "t1": "vdd",
          "t2": "n1"
        }
      },
      {
        "type": "nmos",
        "id": "m1",
        "device": {
          "type": "m1",
          "deafult": 1.5,
          "min": 1,
          "max": 2
        },
        "netlist": {
          "drain": "n1",
          "gate": "vin",
          "source": "vss"
        }
      }
    ]
    

    您可以在以下在线资源中阅读更多相关信息:

    【讨论】:

    • 感谢您的回复.. 有没有其他解决方案可以匹配 JSON 而无需更改它?另一种解决方法我正在考虑使用电阻类型和 m1 而不是设备创建属性,但它会强制我为每个设备添加属性将添加到系统中。
    • 唯一的其他方法是创建一个自定义反序列化器。但是改变 JSON 是不可能的吗?您构建 JSON 的方式让您的生活变得更加艰难,而不是更轻松,因此请考虑更改它而不是解决它。
    猜你喜欢
    • 2011-05-11
    • 2018-07-24
    • 2012-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-03
    • 1970-01-01
    • 2020-06-22
    相关资源
    最近更新 更多