如何获取SOAP头

5

这是请求

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:soap="http://soap.ws.server.wst.fit.cvut.cz/">
    <soapenv:Header>
        <userId>someId</userId>
    </soapenv:Header>
    <soapenv:Body>
    ...
    </soapenv:Body>
</soapenv:Envelope>

我想获取那个userId

我尝试了这个:

private List<Header> getHeaders() {
    MessageContext messageContext = context.getMessageContext();
    if (messageContext == null || !(messageContext instanceof WrappedMessageContext)) {
        return null;
    }
    Message message = ((WrappedMessageContext) messageContext).getWrappedMessage();
    return CastUtils.cast((List<?>) message.get(Header.HEADER_LIST));
}

private String getHeader(String name) {
    List<Header> headers = getHeaders();
    if (headers != null) {
        for (Header header : headers) {
            logger.debug(header.getObject());
            // return header by the given name                   
        }
    }
    return null;
}

它记录了 [userId : null]。我如何获取值,为什么那里是null

5个回答

8
“[userId:null]”通常是DOM元素的“toString”输出。如果您执行类似以下操作的操作,则很可能会看到此输出:
logger.debug(header.getObject().getClass())

您将看到它是某种DOM元素子类。因此,类似于以下内容:

logger.debug(((Element)header.getObject()).getTextContent())

可能会打印文本节点。


7
    import javax.xml.soap.*;

    SOAPPart part = request.getSOAPPart();
    SOAPEnvelope env = part.getEnvelope();
    SOAPHeader header = env.getHeader();
    if (header == null) {
        // Throw an exception
     }

    NodeList userIdNode = header.getElementsByTagNameNS("*", "userId");
    String userId = userIdNode.item(0).getChildNodes().item(0).getNodeValue();

1
不知道这段代码片段的效率和可靠性如何,但它对我来说运行良好 ;) - Kaliyug Antagonist
我发现这个答案很有帮助,因为它(正确地)展示了如何从SOAP头中提取内容。 - Tim Biegeleisen
SOAPPart part = request.getSOAPPart(); 这部分让我出现了错误,因为它无法识别请求。 - Nithil George
3
你如何获取这里的请求? - kosgeinsky

2
您可以在不使用拦截器和JAXB的情况下获取SOAP标头。
在您的service_impl类中添加以下内容:
public class YourFunctionNameImpl implements YourFunctionName{

@Resource
private WebServiceContext context;

private List<Header> getHeaders() {
    MessageContext messageContext = context.getMessageContext();
    if (messageContext == null || !(messageContext instanceof WrappedMessageContext)) {
        return null;
    }

    Message message = ((WrappedMessageContext) messageContext).getWrappedMessage();
    List<Header> headers = CastUtils.cast((List<?>) message.get(Header.HEADER_LIST));
    return headers;
}

然后在您的函数中,您可以使用:

List<Header> headers = getHeaders();
        for(Iterator<Header> i = headers.iterator(); i.hasNext();) { 
            Header h = i.next(); 
            Element n = (Element)h.getObject(); 

            System.out.println("header name="+n.getLocalName()); 
            System.out.println("header content="+n.getTextContent()); 
    }

1
这种方法对我来说更方便,在服务层访问SOAP headers。 CXF 常见问题解答: http://cxf.apache.org/faq.html#FAQ-HowcanIaddsoapheaderstotherequest/response? - burcakulug

1
在CXF拦截器中添加以下代码,我们可以在服务器端获取SOAP标头。
创建一个类,例如: public class ServerCustomHeaderInterceptor extends AbstractSoapInterceptor {
@Resource
private WebServiceContext context;

public ServerCustomHeaderInterceptor() {
    super(Phase.INVOKE);

}

@Override
public void handleMessage(SoapMessage message) throws Fault,JAXBException {
    System.out.println("ServerCustomHeaderInterceptor  handleMessage");
    JAXBContext jc=null;
    Unmarshaller unmarshaller=null;
    try {
    jc = JAXBContext.newInstance("org.example.hello_ws");
    unmarshaller = jc.createUnmarshaller();
    } catch (JAXBException e) {
    e.printStackTrace();
    }


    List<Header> list = message.getHeaders();
    for (Header header : list) {
            ElementNSImpl el = (ElementNSImpl) header.getObject();
        ParentNode pn= (ParentNode) el.getFirstChild();
        //Node n1= (Node) pn;
        //Node n1= (Node) el.getFirstChild();

        CustomHeader customHeader=(CustomHeader)  unmarshaller.unmarshal(el.getFirstChild());


    }

}

接下来,我们需要将其作为拦截器注入,例如

 <jaxws:inInterceptors>
        <bean class="org.apache.cxf.interceptor.LoggingInInterceptor" />
    <bean class="org.example.hellows.soap12.ServerCustomHeaderInterceptor" />
   </jaxws:inInterceptors>

在您的服务器上下文XML中。

根据您的要求,我们可能需要更改几行。基本流程将按如下方式工作。


0
有一个名为MessageContext的消息上下文,你可以使用以下代码:
HeaderList hl = (HeaderList) messageContext.get(JAXWSProperties.INBOUND_HEADER_LIST_PROPERTY);

这将使您可以访问所有的SOAP头。


3
据我所见,HeaderListJAXWSPropertiescom.sun.xml.internal.ws.*包中的类。我真的不想使用它们... - user219882
MessageContext是常规Java包的一部分。 - Guillaume Polet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接