将子对象从 JSON 绑定到父属性 java

Posted

技术标签:

【中文标题】将子对象从 JSON 绑定到父属性 java【英文标题】:binding a child object from JSON to parent attribute 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"
    
  
]

提前致谢

【问题讨论】:

【参考方案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"
    
  
]

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

https://www.baeldung.com/jackson-inheritance https://www.tutorialspoint.com/jackson_annotations/jackson_annotations_jsontypename.htm

【讨论】:

感谢您的回复.. 有没有其他解决方案可以匹配 JSON 而无需更改它?另一种解决方法我正在考虑使用电阻类型和 m1 而不是设备创建属性,但它会强制我为每个设备添加属性将添加到系统中。 唯一的其他方法是创建一个自定义反序列化器。但是改变 JSON 是不可能的吗?您构建 JSON 的方式让您的生活变得更加艰难,而不是更轻松,因此请考虑更改它而不是解决它。

以上是关于将子对象从 JSON 绑定到父属性 java的主要内容,如果未能解决你的问题,请参考以下文章

实体框架 6:将子对象添加到父列表与将子对象的导航属性设置为父对象

将 JSON 子对象属性绑定到 Jackson 中的 Java 对象字段

Angular 2将输入绑定到函数调用

WPF 绑定到父 DataContext

通过 MVVM 模式创建 UserControl - DataContext 并绑定到父级

将子对象复制到父类型指针中