使用JAXB的XML元素内的marshall属性

时间:2018-09-11 13:23:31

标签: spring jaxb spring-data-jpa

我使用Spring JPA,并且具有以下实体:

@Entity
@Table(name = Constants.ENTITY_TABLE_PREFIX + "ENTRY")
@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement(name = "monObj_info")
public class EntryXML implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @XmlAttribute
    private long id;

    @Column(name = "ip_address", nullable = true)
    @XmlElement
    private String ip_address;

    @Column(name = "network_element_name", nullable = false)
    @XmlElement
    private String network_element_name;

    public EntryXML() {}

    public EntryXML(long id, String ip_address, String   network_element_name) {
        super();
        this.id = id;
        this.ip_address = ip_address;
        this.network_element_name = network_element_name;
    }

    public long getId() {
        return id;
    }

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

    public String getIp_address() {
        return ip_address;
    }

    public void setIp_address(String ip_address) {
        this.ip_address = ip_address;
    }

    public String getNetwork_element_name() {
        return network_element_name;
    }

    public void setNetwork_element_name(String network_element_name) {
        this.network_element_name = network_element_name;
    }

}

和端点:

@RestController
public class EntryXMLEndpoint {

    @Autowired
    private IEntryXMLService service;

    @RequestMapping(value = "/restxml", produces = { "application/xml" })
    public EntryXML findEntries() {
        EntryXML record = service.findById(1);
        return record;
    }

}

现在请求的响应是:

<monObj_info id="1">
 <atribute name="ip_address" value="xx.xxx.xxx.x"/>
 <atribute name="network_element_name" value="xxxxxx"/>
</monObj_info>

我得到的当然是:

<monObj_info id="1">
  <ip_address>xx.xxx.xxx.x</ip_address>
  <network_element_name>xxxxxx</network_element_name>
</monObj_info>

我读过类似的文章,但是问题是我无法在Entity Class中创建包含必需元素的List,因为它不会与相应表中的任何列进行映射,有任何建议吗?

1 个答案:

答案 0 :(得分:0)

您可以以直截了当但有点黑的方式实现目标。

由于您不希望使用ip_addressnetwork_element_name属性 要直接进行编组和解组,您需要删除其@XmlElement批注 并添加@XmlTransient

相反,您希望一些<atribute name="..." value="..." />元素被编组和解组。 因此,您需要在EntryXML类中添加以下内容:

  • 一个attributes属性,其中包含属性列表。 它用@XmlElement注释,因此它将成为XML编组和解组的一部分。 它用@Transient注释,以便成为数据库持久性的一部分。
  • 一个简单的帮助器类Attribute,用于保存名称和值。 namevalue带有@XmlAttribute注释,因此它们将成为XML编组和解组的一部分。
  • 一个Marshal Event Callback在元帅之前) 用于从ip_addressnetwork_element_name进行转换 到attributes列表中。
  • 一个Unmarshal Event Callback之后的元帅) 进行相反的转换。

@XmlElement(name = "atribute")
@Transient  // from package javax.persistence
private List<Attribute> attributes;

// there is no need for getAttributes and setAttributes methods

private static class Attribute {

    @SuppressWarnings("unused")  // called by the unmarshaller
    Attribute() {
    }

    Attribute(String name, String value) {
        this.name = name;
        this.value = value;
    }

    @XmlAttribute
    private String name;

    @XmlAttribute
    private String value;
}

@SuppressWarnings("unused") // this method is called only by the marshaller
private boolean beforeMarshal(Marshaller marshaller) {
    attributes = new ArrayList<>();
    attributes.add(new Attribute("ip_address", ip_address));
    attributes.add(new Attribute("network_element_name", network_element_name));
    return true;
}

@SuppressWarnings("unused") // this method is called only by the unmarshaller
private void afterUnmarshal(Unmarshaller unmarshaller, Object parent) {
    if (attributes != null) {
        for (Attribute attribute : attributes) {
            switch (attribute.name) {
            case "ip_address":
                ip_address = attribute.value;
                break;
            case "network_element_name":
                network_element_name = attribute.value;
                break;
            }
        }
    }
}

然后XML输出将如下所示:

<monObj_info id="1">
    <atribute name="ip_address" value="xx.xxx.xxx.x"/>
    <atribute name="network_element_name" value="xxxxxx"/>
</monObj_info>
相关问题