使用Spring WS获取SOAP Header的内容

Jan*_*ert 0 java spring soap web-services spring-ws

我正在尝试构建一个端点,该端点将从客户端接收SOAP消息。我收到的消息在soap标头中包含用户名和密码...

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://www.company.com/Application">
    <soapenv:Header  xmlns:wsse="http://__________.xsd">
        <wsse:Security >
            <wsse:UsernameToken>
                <wsse:Username>username</wsse:Username>
                <wsse:Password>password</wsse:Password>
            </wsse:UsernameToken>
        </wsse:Security>

   </soapenv:Header>
   <soapenv:Body>
Run Code Online (Sandbox Code Playgroud)

我使用的是Spring WS-显而易见的解决方案是在内部创建一个过滤器web.xml,该过滤器将完全绕过Spring WS,解析SOAP消息,提取用户名和密码,然后继续到Spring WS,它将再次解析SOAP。

有没有一种方法可以在不绕过Spring WS的情况下获取标头的内容?

我尝试在其中添加一个bean sws:interceptors

<sws:interceptors>

    <!-- extract Security details from Header -->
    <bean class="com.company.application.service.SecurityInterceptorService" />

    <!-- log full Body of request -->
    <bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"/>

    <!-- validate Request against XSD to make sure it's a valid request -->
    <bean id="CompanyApplication" class="com.company.application.interceptor.ValidatingInterceptor">
        <property name="schema" value="/WEB-INF/_______________.xsd" />
        <property name="validateRequest" value="true" />
        <property name="validateResponse" value="true" />
    </bean>

</sws:interceptors>
Run Code Online (Sandbox Code Playgroud)

然后实现该类:

public class SecurityInterceptorService implements EndpointInterceptor {


    @Override
    public boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception {

        System.out.println("---------------");
        System.out.println("handleRequest")                                             ;
        System.out.println("---------------");


        return true;
    }

    @Override
    public boolean handleResponse(MessageContext messageContext, Object endpoint) throws Exception {

        System.out.println("---------------");
        System.out.println("handleResponse");
        System.out.println("---------------");



        return true;
    }

    @Override
    public boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception {

        System.out.println("---------------");
        System.out.println("handleFault");
        System.out.println("---------------");


        return true;
    }

    @Override
    public void afterCompletion(MessageContext messageContext, Object endpoint, Exception ex) throws Exception {

        System.out.println("---------------");
        System.out.println("afterCompletion");
        System.out.println("---------------");

    }



}
Run Code Online (Sandbox Code Playgroud)

endpoint在调试模式下,当handleRequest遍历内部的许多层和层之后,仅包含有关端点内部的数据messageContext,我似乎无法发现标头的内容。

我在寻找的内容是内部内容messageContext吗?如果要查找,该如何访问?

Vir*_*oll 5

messageContext对象中,您可以检索请求或响应(在您的情况下,我想您需要该请求)。

请求/响应基本上是WebServiceMessage。如果检查webServiceMessage,将看到该对象可以转换为SoapMessage。从soap消息中,您现在可以获取soap标头。

WebServiceMessage webServiceMessageRequest = messageContext_.getRequest();
SoapMessage soapMessage = (SoapMessage) webServiceMessageRequest;
SoapHeader soapHeader = soapMessage.getSoapHeader()
Run Code Online (Sandbox Code Playgroud)

之后,您可能想要获取对象并将其转换为DOMSource对象,然后获取Node对象,这使信息检索更加容易。

Source bodySource = soapHeader .getSource();
DOMSource bodyDomSource = (DOMSource) bodySource;
Node bodyNode = _bodyDomSource.getNode();
Run Code Online (Sandbox Code Playgroud)