【问题标题】:Way to add xml root element annotation for generated class?为生成的类添加xml根元素注释的方法?
【发布时间】:2016-04-16 11:16:18
【问题描述】:

我已经从 WSDL 文件生成了 JAXB 类,我想要做的是将 XML 转换为 Java 对象。下面是生成的 JAXB 类示例:

XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "GetProductListResponse", propOrder = {
    "productList",
    "productListDate",
    "failed",
    "failedDescription"
})
public class GetProductListResponse {

@XmlElementRef(name = "ProductList", namespace = "http://productService.productsdata", type = JAXBElement.class, required = false)
protected JAXBElement<ArrayOfProductListDetail> productList;
@XmlElementRef(name = "ProductListDate", namespace = "http://productService.productsdata", type = JAXBElement.class, required = false)
protected JAXBElement<String> productListDate;
@XmlElement(name = "Failed")
protected boolean failed;
@XmlElement(name = "FailedDescription", required = true, nillable = true)
protected String failedDescription;

...
}

我需要转换为GetProductListResponse 对象的XML 示例存储在products.xml 文件中,如下所示:

<GetProductListResult xmlns="http://productService.productsdata">
            <ProductList>
               <ProductListDetail>
                  <ProductName>SomeProductName</ProductName>
                  <ProductCost>9,45</ProductCost>
               </ProductListDetail>
               <ProductListDate>09.09.2015</ProductListDate>
               <Failed>false</Failed>
               <FailedDescription/>
            </ProductList>
</GetProductListResult>

convertXmlProductsTest 方法内部是设置转换调用的位置 - 为此目的使用 jaxb unmarshaller

public class ProductHandler {

    public static GetProductListResponse convertXmlProductsTest(){
        try {
            JAXBContext jaxbContext = JAXBContext.newInstance(GetProductListResponse.class);
            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
            GetProductListResponse retval = (GetProductListResponse) jaxbUnmarshaller.unmarshal(new File("products.xml"));

            return retval;
        } catch (JAXBException ex) {
            Logger.getLogger(ProductMockWs.class.getName()).log(Level.SEVERE, null, ex);
        }
        throw new UnsupportedOperationException("XML to Java object conversion failed.");
    }
}

问题是生成的 JAXB 类 GetProductListResponse 不包含 @XmlRootElement 注释,因此此转换失败并出现著名的错误消息 javax.xml.bind.UnmarshalException: unexpected element ... Expected elements are ...

当我手动在GetProductListResponse类中添加@XmlRootElement注解,并将其设置为:

@XmlRootElement(name="GetProductsListResult")
public class GetProductListResponse { ...}

转换成功。

问题: 有没有办法从该类外部为生成的类(GetProductListResponse)设置@XmlRootElement

我想避免自定义生成的类并且我不想更改 WSDL 定义。我还阅读了有关设置运行时注释的信息,但我想避免使用任何 Java 字节码操纵器(如 Javassist)。

【问题讨论】:

    标签: java xml jaxb wsdl


    【解决方案1】:
        JAXBContext jaxbContext = JAXBContext.newInstance(GetProductListResponse.class);
        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
    
        JAXBElement<GetProductListResponse> root = jaxbUnmarshaller.unmarshal(new StreamSource(
                file), GetProductListResponse.class);
        GetProductListResponse productListResponse = root.getValue();
    

    由于缺少@XmlRootElement,这篇文章对我帮助很大。看看:

    http://www.source4code.info/2013/07/jaxb-marshal-unmarshal-with-missing.html

    你可以在这里找到你的错误,看看你能做什么!希望能帮助到你 !

    【讨论】:

      【解决方案2】:

      这在Jackson json/xml parser library 中是可能的。 Jackson fully supports JAXB annotations 和它的 mixin feature 允许您从源外部向类添加注释。

      【讨论】:

      • 感谢@sharonbn 的回复!我按照您的建议尝试了 Jackson 库,但我无法解析 XML,因为某些生成的类没有生成设置器或无参数构造函数(即 ArrayOfProductListDetail)。我还尝试将 jaxb annotate 插件与 maven 一起使用并添加绑定 jxb 文件,但是 xsd 文件写得不好,所以 maven-jaxb2-compiler 抱怨很多 - 引用 xsd 文件中大约数百个地方报告了冲突错误.你有什么其他的建议?提前致谢。
      • 抱歉,没有其他建议。
      猜你喜欢
      • 2018-02-18
      • 2016-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-05
      • 1970-01-01
      相关资源
      最近更新 更多