0

你好!我正在尝试向 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。

任何想法?

4

2 回答 2

1

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

于 2012-11-22T02:25:40.960 回答
1

这就是我使用该方法的方式(出于某种原因,使用以前的方法未编写标头):

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();
    }
}
于 2012-11-22T17:56:26.003 回答