SOAP:将方法从AXIS 1.4迁移到CXF以添加新标头

时间:2012-11-22 01:00:29

标签: java soap cxf axis

嗨!我正在尝试向SOAP调用添加标头。 我是处理Web服务的新手。

每次我需要使用Web服务下载文件时,我需要添加一个标题,如:

<UserIdHeader xmlns="http://www.stats.com/">
    <TicketId>defe3a08-4c8a-47c4-9303-98e09c475532</TicketId>
</UserIdHeader>

我正在使用CXF。我有一个用Axis 1.4制作的例子。 唯一剩下的就是(我希望)是添加这个标题。

这是我必须更新的内容:

private static void addHeader(String ticketId) {
    SOAPHeaderElement header = new SOAPHeaderElement("http://www.stats.com/", "UserIdHeader");
    SOAPElement node;

    org.apache.axis.client.Stub s = (Stub) service;
    s.clearHeaders();

    try {
        node = header.addChildElement("TicketId");
        node.addTextNode(ticketId);
        s.setHeader((org.apache.axis.message.SOAPHeaderElement) header);
    } catch (SOAPException e) {
      e.printStackTrace();
    }
}

这就是我尝试更新它的方式:

private static void addHeader(String ticketId) throws JAXBException, ParserConfigurationException {
    Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();

    Element eTicketId = doc.createElement("TicketId");
    eTicketId.setTextContent(ticketId);

    List<Header> headers = new ArrayList<Header>();
    Header header = new Header(new QName("http://www.stats.com/", "UserIdHeader"), eTicketId, 
            new JAXBDataBinding(String.class));
    headers.add(header);

    BindingProvider.class.cast(service).getRequestContext().put(Header.HEADER_LIST, headers);
}

但我得到以下例外:

[PhaseInterceptorChain] Interceptor for {http://www.stats.com/}Service#{http://www.stats.com/}GetFileList has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: Marshalling Error: org.apache.xerces.dom.ElementImpl is not known to this context
    at org.apache.cxf.jaxb.JAXBEncoderDecoder.marshall(JAXBEncoderDecoder.java:261)
    at org.apache.cxf.jaxb.io.DataWriterImpl.write(DataWriterImpl.java:168)
    at org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor.writeSoapEnvelopeStart(SoapOutInterceptor.java:156)
    at org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor.handleMessage(SoapOutInterceptor.java:81)
    at org.apache.cxf.binding.soap.interceptor.SoapOutInterceptor.handleMessage(SoapOutInterceptor.java:61)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262)
    at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:531)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:464)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:367)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:320)
    at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:89)
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:134)

我甚至试过添加一个拦截器,但我不知道如何传递ticketId。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

如果要创建DOM元素,则不应将数据绑定设置到Header对象中。如果您使用的是JAXB(或其他)类型,则只需要数据绑定。 CXF直接处理DOM元素。

答案 1 :(得分:0)

这就是我使用该方法的方法(出于某种原因,使用之前的方法未写入标题):

private static void addHeader(String ticketId) {
    try {
        SOAPFactory sf = SOAPFactory.newInstance();
        SOAPElement userIdHeaderElement = sf.createElement(new QName("http://www.stats.com/", "UserIdHeader"));
        SOAPElement ticketIdElement = sf.createElement(new QName(null, "TicketId"));
        ticketIdElement.addTextNode(ticketId);
        userIdHeaderElement.addChildElement(ticketIdElement);
        List<Header> headers = new ArrayList<Header>();
        Header dummyHeader = new Header(new QName("http://www.stats.com/"), userIdHeaderElement);
        headers.add(dummyHeader);
        BindingProvider.class.cast(service).getRequestContext().put(Header.HEADER_LIST, headers);
    } catch (SOAPException e) {
        e.printStackTrace();
    }
}