我完全是JAXB架构的新手 . 但这就是我要做的事情,简而言之 .
我正在创建一个Web应用程序,客户端将首先注册他的xsd,然后根据xsd发送他的xml / json数据 .
对于xsd的注册,我使用的是XJC(不是作为maven插件,而是来自java代码本身:
SchemaCompiler sc = XJC.createSchemaCompiler();
File schemaFile = new File(schemaPath);
InputSource is = new InputSource(new FileInputStream(schemaFile));
is.setSystemId(schemaFile.getAbsolutePath());
sc.parseSchema(is);
S2JJAXBModel model = sc.bind();
JCodeModel jCodeModel = model.generateCode(null, null);
jCodeModel.build(new File(outputDirectory));
通过XSD看起来像:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="Metadata" type="Metadata" />
<xsd:complexType name="Metadata">
<xsd:sequence>
<xsd:element name="MicroscopeStagePosition"
type="MicroscopeStagePosition" maxOccurs="1" minOccurs="1">
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="MicroscopeStagePosition">
<xsd:sequence>
<xsd:element name="Start" type="xsd:string"/>
<xsd:element name="End" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
我从上面创建了JAXB annoted POJO类,创建的2个类是:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Metadata", propOrder = {
"microscopeStagePosition"
})
public class Metadata {
@XmlElement(name = "MicroscopeStagePosition", required = true)
protected MicroscopeStagePosition microscopeStagePosition;
public MicroscopeStagePosition getMicroscopeStagePosition() {
return microscopeStagePosition;
}
public void setMicroscopeStagePosition(MicroscopeStagePosition value) {
this.microscopeStagePosition = value;
}
}
和
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "MicroscopeStagePosition", propOrder = {
"start",
"end"
})
public class MicroscopeStagePosition {
@XmlElement(name = "Start", required = true)
protected String start;
@XmlElement(name = "End", required = true)
protected String end;
public String getStart() {
return start;
}
public void setStart(String value) {
this.start = value;
}
public String getEnd() {
return end;
}
public void setEnd(String value) {
this.end = value;
}
}
现在我的想法是有一个通用的带注释的类,它将包装这些将在实时创建的上面的类(这个类是真实创建的,因此可以有任何需要的东西) .
问题是我没有xsd会来,因此rootelement没有帮助 . 所以我想创建一个围绕创建的JAXB类的包装器,然后只处理所有API中的这个包装器类 .
我已经实时创建了以下课程:
public class MyModel {
@XmlElement(required = true)
protected Metadata Metadata;
@XmlElement(required = true)
protected MicroscopeStagePosition MicroscopeStagePosition;
}
是否可以基于此包装类解组传入的XML . 请注意,不能强制传入的XML包含MyModel的根元素 . 所以我尝试创建根JAXBElement,然后将其分配给包装类:
MyModel je = new MyModel();
JAXBContext jaxbContext = JAXBContextFactory.createContext(new Class[] {MyModel.class}, null);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
InputStream is = new ByteArrayInputStream(sIncomingMetadataXML.getBytes());
JAXBElement<MyModel> root = jaxbUnmarshaller.unmarshal(new StreamSource(
is), MyModel.class);
je = root.getValue();
如果我用@XmlRootElement @XmlAccessorType(XmlAccessType.FIELD)注释MyModel并从我的api返回je它的null子对象xml:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<MyModel/>
如果没有,则出现错误:
找不到Java类a和MIME媒体类型application / xml的消息正文编写器 .
那么我可以创建一个像上面那样的包装类,如果是这样的话,或者我在这里完全错过了什么
1 回答
在评论中未经用户批准"Note the incoming XML cannot be forced to have the root element of MyModel in it" .
你没有直接将流传递给Jaxb,而是读入
StringBuffer
,我经常处理不同的UTF Headers ,记录我喜欢的ecc .在你的情况下添加迫切需要的标签 .
Read 将流转换为
StringBuffer sb
(参见示例Read/convert an InputStream to a String)Insert
StringBuffer
中需要的标签Unmarshaller
StringBuffer