我完全是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类,并且创建了两个类:
@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它的一个空子对象xml:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<MyModel/>
如果没有,则会出现错误:
Java类和MIME媒体类型的消息正文编写器 找不到application / xml。
那么我可以创建一个上面的包装类,如果是这样的话,或者我在这里完全错过了什么
答案 0 :(得分:0)
不考虑“请注意,传入的XML不能强制在其中包含MyModel的根元素”作为用户在评论中批准。
而不是将流直接传递给Jaxb,而是读入StringBuffer
,我经常处理不同的UTF标题,记录我喜欢ecc。
在你的情况下添加迫切需要的标签。
将流转换为StringBuffer sb
(请参阅示例Read/convert an InputStream to a String)
在StringBuffer
Unmarshaller StringBuffer
StringReader reader = new StringReader(sb.toString());
JAXBElement<MyModel> root = getUnmarshaller().unmarshal(reader)