我遇到了JAXB的以下问题:看起来JAXB正在分析从最深的子类到父类的属性,并且子属性具有优先级。我想以某种方式改变这种行为。特别是:
儿童班:
package test.sub;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlTransient;
@XmlAccessorType(XmlAccessType.NONE)
public class BasicDocument {
private String comment;
public String getComment() {
return comment;
}
public void setComment(String cost) {
this.comment = cost;
}
}
父类:
package test;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import test.sub.BasicDocument;
@XmlRootElement(name="Description", namespace="http://www.w3.org/1999/02/22-rdf-syntax-ns#")
@XmlAccessorType(XmlAccessType.PROPERTY)
class Document extends BasicDocument {
private String identifier;
@XmlElement(name = "identifier", namespace = "http://purl.org/dc/terms/")
public String getIdentifier() {
return identifier;
}
public void setIdentifier(String identifier) {
this.identifier = identifier;
}
@Override
@XmlElement(name = "abstract", namespace = "http://purl.org/dc/terms/")
public String getComment() {
return super.getComment();
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
}
编组工作正常:
Document document = new Document();
document.setIdentifier("12A");
document.setComment("special");
StringWriter w = new StringWriter();
jaxbContext.createMarshaller().marshal(document, new StreamResult(w));
System.out.println(w);
输出:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:Description xmlns:ns2="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/dc/terms/">
<abstract>special</abstract>
<identifier>12A</identifier>
</ns2:Description>
但是编组会忽略子BasicDocument
类中的属性(t.xml
正是上面的XML):
JAXBContext jaxbContext = JAXBContext.newInstance(Document.class);
Document document = (Document) jaxbContext.createUnmarshaller().unmarshal(Document.class.getResourceAsStream("t.xml"));
System.out.println("out: " + document);
输出:
out: Document[identifier=12A,comment=<null>]
预期:
out: Document[identifier=12A,comment=special]
基本上@XmlAccessorType(XmlAccessType.NONE)
上的BasicDocument
(请参阅Ignore a parent class when Serializing to XML)无效。还要在包package-info.java
中创建test.sub
(请参阅@XmlTransient on third-party or external super class),如下所示:
@XmlAccessorType(XmlAccessType.NONE)
package test.sub;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
没有效果。只有@XmlTransient public class BasicDocument
有效。理想情况下,我不想在子项上添加任何注释,只能通过package-info.java
控制此行为。我怎么能这样做?
在JDK 1.6.0_27上测试,另外在类路径中使用JAXB 2.2.4-1运行时。
是功能还是错误?
答案 0 :(得分:2)
您只需要将setComment
方法添加到Document
类。没有它,即使该方法存在于父类中,它也被视为只写属性。
public void setComment(String comment) {
super.setComment(comment);
}
Document
package test;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import test.sub.BasicDocument;
@XmlRootElement(name="Description", namespace="http://www.w3.org/1999/02/22-rdf-syntax-ns#")
@XmlAccessorType(XmlAccessType.PROPERTY)
class Document extends BasicDocument {
private String identifier;
@XmlElement(name = "identifier", namespace = "http://purl.org/dc/terms/")
public String getIdentifier() {
return identifier;
}
public void setIdentifier(String identifier) {
this.identifier = identifier;
}
@Override
@XmlElement(name = "abstract", namespace = "http://purl.org/dc/terms/")
public String getComment() {
return super.getComment();
}
public void setComment(String comment) {
super.setComment(comment);
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
}
}