如果名称空间声明在SOAP信封上,如何使用JAXB解组SOAP响应?

如果已经删除了soap信封,则JAXB只能解组XML。 但是,我试图解组的SOAP响应在soap信封上有其名称空间声明。 如果我删除soap信封,名称空间声明也将被删除。 因此,标签的前缀将指无。 这会导致JAXB抛出错误。 如果在SOAP信封上声明名称空间,如何使用JAXB解组SOAP响应?

我需要解组的XML的类似示例如下:

   123456789    

如果我移除肥皂信封会发生这种情况:

  123456789  

如果我删除了soap信封,名称空间声明也将消失。 JAXB将无法解组上述xml,因为缺少前缀“ns”的命名空间定义。 因此,它将返回"The prefix "ns" for element "ns:getNumberResponse" is not bound." 错误信息。 我如何解决它?

请注意我使用的是JDK 1.5。 我不确定在JDK 1.6中是否有办法解决这个问题。 我能够使用JAXB,因为我下载了使用JAXB所需的jar。

您可以使用StAX解析器来解析SOAP消息,然后将XMLStreamReader推进到getNumberResponse元素,并使用带有类参数的unmarshal方法。 Java SE 6中包含StAX解析器,但您需要为Java SE 5下载一个.Stickstox是一种流行的StAX解析器。

响应

 package forum11465653; public class Response { private long number; public long getNumber() { return number; } public void setNumber(long number) { this.number = number; } } 

演示

XMLStreamReader具有NamespaceContextNamespaceContext知道当前级别的所有活动命名空间声明。 您的JAXB(JSR-222)实现将能够利用它来获取必要的信息。

 package forum11465653; import java.io.FileReader; import javax.xml.bind.*; import javax.xml.stream.*; public class Demo { public static void main(String[] args) throws Exception{ XMLInputFactory xif = XMLInputFactory.newFactory(); XMLStreamReader xsr = xif.createXMLStreamReader(new FileReader("src/forum11465653/input.xml")); xsr.nextTag(); // Advance to Envelope tag xsr.nextTag(); // Advance to Body tag xsr.nextTag(); // Advance to getNumberResponse tag System.out.println(xsr.getNamespaceContext().getNamespaceURI("ns")); JAXBContext jc = JAXBContext.newInstance(Response.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); JAXBElement je = unmarshaller.unmarshal(xsr, Response.class); System.out.println(je.getName()); System.out.println(je.getValue()); } } 

产量

 http://example.com/ {http://example.com/}getNumberResponse forum11465653.Response@781f6226 

您可以使用DOM解析器解析整个SOAP消息,该解析器能够在解析时解析所有命名空间。 然后从生成的DOM树中提取所需的元素,并将其传递给unmarshaller。

DomDemo

 package forum11465653; import java.io.File; import javax.xml.bind.*; import javax.xml.parsers.*; import javax.xml.transform.dom.DOMSource; import org.w3c.dom.*; public class DomDemo { public static void main(String[] args) throws Exception{ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setNamespaceAware(true); DocumentBuilder db = dbf.newDocumentBuilder(); Document d = db.parse(new File("src/forum11465653/input.xml")); Node getNumberResponseElt = d.getElementsByTagNameNS("http://example.com/", "getNumberResponse").item(0); JAXBContext jc = JAXBContext.newInstance(Response.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); JAXBElement je = unmarshaller.unmarshal(new DOMSource(getNumberResponseElt), Response.class); System.out.println(je.getName()); System.out.println(je.getValue()); } } 

产量

 {http://example.com/}getNumberResponse forum11465653.Response@19632847