使用JAXB在XML元素中使用marshall属性
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用JAXB在XML元素中使用marshall属性相关的知识,希望对你有一定的参考价值。
我使用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>
我读了类似的帖子,但问题是我无法在我的实体类中创建一个包含所需元素的List,因为它不会映射到相应表中的任何列,有什么建议吗?
答案
你可以直接但有点hackish的方式实现你的目标。
由于您不希望ip_address
和network_element_name
属性直接编组和解组,您需要删除它们的@XmlElement
注释并添加@XmlTransient
。
相反,你想要一些<atribute name="..." value="..." />
元素编组和解组。因此,您需要在EntryXML
类中添加以下内容:
- 包含属性列表的
attributes
属性。它用@XmlElement
注释,因此它将成为XML编组和解组的一部分。它用@Transient
注释,因此它不会成为数据库持久性的一部分。 - 一个简单的帮助类
Attribute
用于保存名称和值。name
和value
用@XmlAttribute
注释,以便它们成为XML编组和解组的一部分。 - Marshal Event Callback(beforeMarshal)用于从
ip_address
和network_element_name
转换到attributes
列表。 - 用于进行相反转换的Unmarshal Event Callback(afterUnmarshal)。
@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>
以上是关于使用JAXB在XML元素中使用marshall属性的主要内容,如果未能解决你的问题,请参考以下文章
Jaxb2Marshaller在春天解组 - 意想不到的元素