从WSDL生成的JAXB POJO看起来很麻烦

时间:2014-08-14 02:07:35

标签: java xml soap jaxb wsdl

我并不擅长SOAP并将WSDL转变为POJO。我设法连接到Web服务并检索我需要的数据。

问题在于遍历WSDL创建的对象层次结构。 存储在生成的类中的大多数变量都是JAXBElement<NameOfJavaClassHere>类型。因此,当我想要该对象时,我需要发出ListOfEntitiesType loe = ents.getListOfEntities().getValue();之类的调用.getValue()是我遇到问题的地方。

是否存在使这种更顺畅的集成的方法?如果我不得不继续做getValue(),那将会导致1000次减产。

感觉就像他们离开了他们不需要的客户层面的间接水平。

我试图用JAXBContent对象解组xml,网上有很多关于如何做到这一点的例子,但在这种情况下它没有用。我的对象是null。

WSDL是否应该让POJO不需要所有这些关于泛型的投射?

我是否在java 1.7附带的wsimport命令中使用了错误的设置?

我是否应该使用不同的wsimport-ish程序来生成我的POJO?

如果我必须坚持使用.getValue()这个东西,我想我更愿意为原始XML创建一个xpath接口,或者把整个事情变成Hashtables和ArrayLists而不是处理它。

至少在那之后,我可以直接访问我想要的信息。

2 个答案:

答案 0 :(得分:1)

有一些用例需要JAXBElement能够按照XML Schema中的定义来转换XML。如果您在生成的模型中看到很多JAXBElement,那么其中一些条件可能就是真的。

  1. 元素同时为nillable="true"minOccurs="0"。在这种情况下,映射字段/属性上的null是什么意思?当属性为JAXBElement时,空值表示该元素不存在,而JAXBElement包装null表示带有xsi:nil="true"的XML元素。
  2. 有两个全局元素具有相同的命名复杂类型。由于在JAXB类中对应于复杂类型,因此需要一种方法来捕获遇到的根元素。
  3. 有一个选择结构,其中foobar元素可以出现,它们是相同的类型。这里需要JAXBElement,因为仅仅遇到String值不足以指示应该对哪个元素进行编组。
  4. 在包含属性的文档中遇到包含xsi:nil的元素。在此示例中,对应于该元素的对象仍然可以被解组以保存属性值,但JAXBElement可以指示该元素为null。
  5. 减少模型中JAXBElement数量的机制

    • generateElementProperty设置为false的绑定文件。

      <?xml version="1.0" encoding="UTF-8"?>
      <bindings xmlns="http://java.sun.com/xml/ns/jaxb" xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
          xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
          version="2.1">
          <globalBindings>
              <generateElementProperty>false</generateElementProperty>
          </globalBindings>
      </bindings>
      
    • XJC的简单插件 - https://jaxb.java.net/2.1.2/docs/vendorCustomizations.html#simple

      <?xml version="1.0" encoding="UTF-8"?>
      <bindings xmlns="http://java.sun.com/xml/ns/jaxb" xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
          xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
          xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
          version="2.1">
          <globalBindings>
              <xjc:simple />
          </globalBindings>
      </bindings>
      

答案 1 :(得分:1)

XML schema可能是在一些官僚统治的影响下发展起来的。考虑一下,例如

<xs:element minOccurs="0" name="DUNSNumber" nillable="true" type="xs:string"/>

会产生一个字段

protected JAXBElement<String> dunsNumber;

导致您(正确地)抱怨的高度间接的获取和设定程序。 - XML Schema条目是什么意思?它表示元素是一个字符串,可以省略,并且必须能够区分空字符串和缺少字符串,即使元素存在

这是一个小实验:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
       version="1.0">
<xs:element name="root" type="RootType"/>
<xs:complexType name="RootType">
  <xs:sequence>
    <xs:element maxOccurs="unbounded" name="elem"  type="ElemType"/>
  </xs:sequence>
</xs:complexType>
<xs:complexType name="ElemType">
  <xs:sequence>
    <xs:element minOccurs="0" name="str01"    type="xs:string"/>
    <xs:element minOccurs="1" name="str1"     type="xs:string"/>
    <!-- The following element compiles to a JAXBElement<String> -->
    <xs:element minOccurs="0" name="str01nil" nillable="true" type="xs:string"/>
    <xs:element minOccurs="1" name="str1nil"  nillable="true" type="xs:string"/>
  </xs:sequence>
</xs:complexType>
</xs:schema>

这是一个XML文件:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
  <elem>
    <str01></str01>
    <str1></str1>
    <str01nil></str01nil>
    <str1nil></str1nil>
  </elem>
  <elem>
    <str1>must be there</str1>
    <str01nil xsi:nil="true"></str01nil>
    <str1nil>must be there</str1nil>
  </elem>
</root>

以下是解组程序打印的内容:

str01    []
str1     []
str01Nil []
str1Nil  []
str01    [null]
str1     [must be there]
str01Nil [null]
str1Nil  [must be there]

如果完全省略<str01nil xsi:nil="true"></str01nil>会怎样?结果将是相同的,方法JAXBElement.getValue()将返回null,就是这样。

现在(对不起答案的长度)我们可以讨论如何返回从XML模式生成的“理智”Java代码。我只需删除nillable =“true”并使用生成的代码。如果你编组,字段中的null将不会产生元素。在unmarshal上,你看到一个带有xsi:nil =“true”的空元素的可能性很小。 (但必须保留minOccurs =“0”。)