spring - 使用 JAXB 编组 XML 元素内的属性
问题描述
我使用 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>
我读过类似的帖子,但问题是我无法在我的实体类中创建一个包含所需元素的列表,因为它不会映射到相应表中的任何列,有什么建议吗?
解决方案
你可以用一种直截了当但有点老套的方式来实现你的目标。
由于您不希望直接对ip_address
andnetwork_element_name
属性进行编组和解组,因此您需要删除它们的@XmlElement
注释并添加@XmlTransient
.
相反,您希望对一些<atribute name="..." value="..." />
元素进行编组和解组。因此,您需要在EntryXML
类中添加以下内容:
- 包含
attributes
属性列表的属性。它带有注释,@XmlElement
因此它将成为 XML 编组和解组的一部分。它带有注释,@Transient
因此它不会成为数据库持久性的一部分。 - 一个简单的帮助类
Attribute
,用于保存名称和值。name
并value
带有注释,@XmlAttribute
以便它们成为 XML 编组和解组的一部分。 - 一个Marshal 事件回调(beforeMarshal),用于
ip_address
在network_element_name
列表之间进行转换attributes
。 - 用于执行相反转换的Unmarshal 事件回调( 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>
推荐阅读
- php - 如何解决启用 php.ini 中的扩展?
- python - 要列出的文件内容,但不是字符串
- android - Failed to find '?attr/textAppearanceCaption' in current theme
- adsense - Where to find accountId and adClientId in AdSense account?
- algorithm - 在记忆的情况下,复杂性如何从 O(2^n) 降低到 O(n^2)?
- c# - 如何缩放图像以适合 TitleView
- javascript - HTML5 图片上传,拖放、裁剪和比例
- functional-programming - 列表:在 Erlang 中具有副作用的映射
- android - Android Samsung ACTION_IMAGE_CAPTURE 未保存为正确的文件名
- c# - 如何使用LINQ C#根据另一个字符串更改字符串内容