如何测试需要soap Headers的Spring-WS Web服务?

问题描述 投票:1回答:3

我有一个spring-ws(2.0.2)服务,我已经实现了需要soap头中的一些自定义元素。我正在尝试使用Spring的MockWebServiceClient生成一个有效的请求来测试调度程序,marshallers等。

我得到的问题是MockWebSerivce似乎只支持Soap Body(有效载荷)。

如何访问生成的soap请求以获取正确的标头?

如果除了Spring的MockWebServiceClient之外还有一个更好的库来执行此操作,那也没关系。

相关链接:http://forum.springsource.org/showthread.php?101708-MockWebServiceClient-amp-WS-Security Add SoapHeader to org.springframework.ws.WebServiceMessage

java integration-testing spring-ws
3个回答
2
投票

当我想用安全性测试spring web服务时,我遇到了类似的问题,我最终使用Spring Interceptors在它们到达终点之前修改了标头,我启用了拦截器仅用于测试。

创建一个拦截器,我实现了SmartEndpointInterceptor,如果你选择,可以使用其他拦截器

public class ModifySoapHeaderInterceptor implements
    SmartEndpointInterceptor 
{
  //WSConstants.WSSE_NS;
   private static final String DEFAULT_SECURITY_URL = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
    private static final String SECURITY_TAG = "Security";
    private static final String SECURITY_PREFIX = "wsse";
    private static final String USER_NAME_TOKEN = "UsernameToken";

    @Override
public boolean handleRequest(MessageContext messageContext, Object endpoint)
        throws Exception 
{
      SaajSoapMessage saajSoapMessage(SaajSoapMessage)messageContext.getRequest());
      SOAPHeader soapHeader = saajSoapMessage.getSaajMessage().getSOAPPart()
            .getEnvelope().getHeader();

       //you can modify header's as you choose
       Name headerElement = saajSoapMessage.getSaajMessage().getSOAPPart()
            .getEnvelope()
            .createName(SECURITY_TAG, SECURITY_PREFIX, DEFAULT_SECURITY_URL);
       SOAPHeaderElement soapHeaderElement = soapHeader
            .addHeaderElement(headerElement);
    SOAPElement usernameToken = soapHeaderElement.addChildElement(
            USER_NAME_TOKEN, SECURITY_PREFIX);

    SOAPElement userNameElement = usernameToken.addChildElement("Username",
            SECURITY_PREFIX);
    userNameElement.addTextNode("userid");//you can inject via spring

    SOAPElement passwordElement = usernameToken.addChildElement("Password",
            SECURITY_PREFIX);
    passwordElement.addTextNode("password");
       return true;
    }
}

在spring上下文中配置此拦截器

  <sws:interceptors>
     <bean class="prasanna.ws.security.wss4j.ModifySoapHeaderInterceptor"/>
  </sws:interceptors>

这将在消息到达终点之前为消息添加必要的安全标头,您仍然可以使用MockWebServiceClient来测试您的Web服务。


0
投票

我确实找到了smock库,它可以完成我真正想要的工作:只需要一个带有整个请求的文本文件。

http://code.google.com/p/smock/wiki/SpringWs

它支持与弹簧提供的相同的请求和响应匹配器。它还使我的测试非常独立。 (而不是仅在我的测试用例中使用的全新类。)


0
投票

如您所述,MockWebServiceClient sendRequest()方法仅使用给定的有效负载设置SOAP主体。它不会触及SOAP标头。

要设置SOAP标头,您还可以创建一个实现RequestCreator接口的类并设置SOAP标头。将此类的实例传递给sendRequest()方法。

例如:

class SoapActionCreator implements RequestCreator {

    private final Source payload;

    public SoapActionCreator(Source payload) {
        this.payload = payload;
    }

    @Override
    public WebServiceMessage createRequest(WebServiceMessageFactory webServiceMessageFactory)
            throws IOException {
        WebServiceMessage webServiceMessage =
                new PayloadMessageCreator(payload).createMessage(webServiceMessageFactory);

        SoapMessage soapMessage = (SoapMessage) webServiceMessage;
        SoapHeader header = soapMessage.getSoapHeader();
        // Add an Action element to the SOAP header
        StringSource headerSource = new StringSource(
                "<wsa:Action xmlns:wsa=\"http://www.w3.org/2005/08/addressing\">https://example.com/foo/bar</wsa:Action>");
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.transform(headerSource, header.getResult());

        return webServiceMessage;
    }

}

然后像这样使用SoapActionCreator

    SoapActionCreator soapActionCreator = new SoapActionCreator(requestPayload);
    mockClient.sendRequest(soapActionCreator).
            andExpect(payload(responsePayload));

其中requestPayload是SOAP请求主体,responsePayload是整个SOAP响应(标题和正文)。

© www.soinside.com 2019 - 2024. All rights reserved.