Java 在JAXB注释对象内使用对象和toXML方法?
我是一名web服务开发人员。在我的雇主那里,他们有一个非常丰富的数据模型,我可能无法改变太多 几乎所有对象都能够通过toXML()方法将自己呈现为XML。可以把它们看作是散列映射,在这里我们直到运行时才知道完整的字段集Java 在JAXB注释对象内使用对象和toXML方法?,java,xml,jaxb,pojo,Java,Xml,Jaxb,Pojo,我是一名web服务开发人员。在我的雇主那里,他们有一个非常丰富的数据模型,我可能无法改变太多 几乎所有对象都能够通过toXML()方法将自己呈现为XML。可以把它们看作是散列映射,在这里我们直到运行时才知道完整的字段集 import java.util.HashMap; import javax.xml.bind.JAXBContext; import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotatio
import java.util.HashMap;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlRootElement
public class Metadata {
@XmlAttribute String serviceVersion = "5.1";
@XmlAttribute String applicationVersion = "12.1";
@XmlElement @XmlJavaTypeAdapter(UserXmlAdapter.class) User user = new User();
static class User extends Row {
public User() {
tablename = "users";
fields.put( "id", "bmauter" );
fields.put( "firstname", "Brian" );
}
}
static class Row {
String tablename = null;
HashMap<String, Object> fields = new HashMap<String, Object>();
public String toXML() {
StringBuilder result = new StringBuilder();
result.append( "<" ).append( tablename );
for( String fieldName : fields.keySet() ) {
result.append( " " ).append( fieldName ).append( "=\"" ).append( fields.get( fieldName ) ).append( "\"" );
}
result.append( "/>" );
return result.toString();
}
}
static class UserXmlAdapter extends XmlAdapter<String, User> {
@Override public User unmarshal( String v ) throws Exception { return null; }
@Override public String marshal( User user ) throws Exception { return user.toXML(); }
}
public static void main( final String[] args ) throws Exception {
JAXBContext context = JAXBContext.newInstance( Metadata.class );
context.createMarshaller().marshal( new Metadata(), System.out );
}
}
我正在尽可能地利用JAXB,因此我的一些web服务对象是常规的POJO注释,正如您所期望的那样。但是,我想在JAXB注释的POJO中添加一个旧对象,并调用其toXML()
例如:
@XmlRootElement
class Metadata {
@XmlAttribute String serviceVersion;
@XmlAttribute String applicationVersion;
@XmlElement User user; // this is our object with it's own toXML method
}
理想情况下,我希望看到封送结果如下:
<metadata serviceVersion="5.1" applicationVersion="12.1">
<user id="bmauter" firstname="Brian"/>
</metadata>
我已经研究过扩展XmlAdapter,但其输出类似于:
<metadata serviceVersion="5.1" applicationVersion="12.1">
<user><user id="bmauter" firstname="Brian"/></user>
</metadata>
用户id=“bmauter”firstname=“Brian”/
然后我想我读了一些东西,让XmlAdapter将我的对象转换成org.w3c.dom.Element。我决定尝试一下,但它失败了,因为“JAXB无法处理接口”
如何将这样一个对象嵌入到常规的JAXB注释POJO中
谢谢
更新:下面是我试图修复的实际示例。(再次更新以显示字段名集在运行时之前是未知的。)
import java.util.HashMap;
导入javax.xml.bind.JAXBContext;
导入javax.xml.bind.annotation.XmlAttribute;
导入javax.xml.bind.annotation.xmlement;
导入javax.xml.bind.annotation.XmlRootElement;
导入javax.xml.bind.annotation.adapters.XmlAdapter;
导入javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlRootElement
公共类元数据{
@XmlAttribute字符串serviceVersion=“5.1”;
@XmlAttribute字符串applicationVersion=“12.1”;
@XmlElement@XmlJavaTypeAdapter(UserXmlAdapter.class)User User=new User();
静态类用户扩展行{
公共用户(){
tablename=“用户”;
字段。put(“id”、“bmauter”);
字段。put(“firstname”、“Brian”);
}
}
静态类行{
字符串tablename=null;
HashMap字段=新的HashMap();
公共字符串toXML(){
StringBuilder结果=新建StringBuilder();
结果。追加(“”);
返回result.toString();
}
}
静态类UserXmlAdapter扩展了XmlAdapter{
@重写公共用户解组(字符串v)引发异常{return null;}
@重写公共字符串封送处理程序(用户)引发异常{return User.toXML();}
}
公共静态void main(最终字符串[]args)引发异常{
JAXBContext context=JAXBContext.newInstance(Metadata.class);
context.createMarshaller().marshal(新元数据(),System.out);
}
}
当您具备以下条件时
@XmlRootElement
class Metadata {
@XmlAttribute String serviceVersion;
@XmlAttribute String applicationVersion;
@XmlElement User user; // this is our object with it's own toXML method
}
用户
对象将根据其映射在元数据
对象的XML中呈现。您无需执行任何特殊操作。谢谢,但我希望toXML的结果出现在JAXB输出中。顺便说一句,你的回答让我很惭愧。@b主持人-我不推荐那种方法。如果您的toXML
方法只是返回一个字符串
,它将无法与其他封送输出(如XMLStreamWriter
,节点
等)一起很好地工作。如果toXML
方法基于JAXB映射,您无论如何都会得到相同的结果。不幸的是,直到运行时我才知道完整的字段集。没有什么可注释的。还有其他适合我的东西吗?如果它回来了怎么办?我如何以编程方式构建它?您是否尝试过将用户声明为@XmlValue-String-user代码>?您可以将用户存储为非jaxb字段,并在getUser()方法中返回其XML。对于给定的父元素,只能有一个@XmlValue注释。尽管如此,它仍然逃避了文本。99.999%的时间它做你想做的事。我只是有点惊讶,我们无法在JAXB对象的中间粘贴外部生成的XML。