针对Wrapper类的JAXB,Unmarshalling和编组。

时间:2016-01-05 11:56:05

标签: xml xsd jaxb marshalling unmarshalling

我完全是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。

那么我可以创建一个上面的包装类,如果是这样的话,或者我在这里完全错过了什么

1 个答案:

答案 0 :(得分:0)

不考虑“请注意,传入的XML不能强制在其中包含MyModel的根元素”作为用户在评论中批准。

而不是将流直接传递给Jaxb,而是读入StringBuffer,我经常处理不同的UTF标题,记录我喜欢ecc。

在你的情况下添加迫切需要的标签。

  1. 流转换为StringBuffer sb(请参阅示例Read/convert an InputStream to a String

  2. StringBuffer

  3. 中根据需要插入代码
  4. Unmarshaller StringBuffer

    StringReader reader = new StringReader(sb.toString());
    JAXBElement<MyModel> root = getUnmarshaller().unmarshal(reader)