Search code examples
springjaxbspring-wsjaxb2

Spring WS is generating empty SOAP Envelop


I want do call a SOAP service with Spring WS WebServiceTemplate. I have used this very often and it always worked so far. But now I just get an soap envelope with empty body:

 <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/><SOAP-ENV:Body/></SOAP-ENV:Envelope>

I have created the request and response classes with the JAXB Maven Plugin. And the generated source code looks exactly like the services which are working.

Example:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(
    name = "startRequest_RequestParameters",
    propOrder = {"url"}
)
@XmlRootElement(
 name = "startRequest"
)
public class StartRequest {
  @XmlElement(
    required = true
  )
  @XmlSchemaType(
    name = "anyURI"
  )
  protected String url;

  public StartRequest() {
  }

  public String getUrl() {
    return this.url;
  }

  public void setUrl(String value) {
    this.url= value;
  }
}

I call the webservice template with marshallSendAndReceive

StartRequest request = new StartRequest();
request.setUrl(url);
StartResponse response = (StartResponse) webServiceTemplate.marshalSendAndReceive(endpointUrl, request);

I configure the WebServiceTemplate with java configuration:

public WebServiceTemplate startRequestWebServiceTemplate() throws Exception {
    return createWebServiceTemplate(createMarshaller(), createSecurityInterceptor(username, password), createMessageSender(proxyHost, proxyPort));
}


private WebServiceTemplate createWebServiceTemplate(Jaxb2Marshaller marshaller, ClientInterceptor securityInterceptor, WebServiceMessageSender messageSender) {
    WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
    webServiceTemplate.setMarshaller(marshaller);
    webServiceTemplate.setUnmarshaller(marshaller);
    webServiceTemplate.setMessageSender(messageSender);
    if (securityInterceptor != null) {
        webServiceTemplate.setInterceptors((ClientInterceptor[]) Arrays.asList(securityInterceptor, createLoggingInterceptor()).toArray());
    } else {
        webServiceTemplate.setInterceptors((ClientInterceptor[]) Arrays.asList(createLoggingInterceptor()).toArray());
    }
    webServiceTemplate.setCheckConnectionForFault(true);
    webServiceTemplate.afterPropertiesSet();
    return webServiceTemplate;
}

private Jaxb2Marshaller createMarshaller() throws Exception {
    Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
    jaxb2Marshaller.setClassesToBeBound(StartRequest.class, StartResponse.class);
    jaxb2Marshaller.afterPropertiesSet();
    return jaxb2Marshaller;
}

private ClientInterceptor createLoggingInterceptor() {
    return new SoapLoggingInterceptor(systemName);
}

private Wss4jSecurityInterceptor createSecurityInterceptor(String username, String password) {
    Wss4jSecurityInterceptor wss4jSecurityInterceptor = new Wss4jSecurityInterceptor();
    wss4jSecurityInterceptor.setSecurementPasswordType("PasswordText");
    wss4jSecurityInterceptor.setSecurementActions("UsernameToken");
    wss4jSecurityInterceptor.setSecurementUsername(username);
    wss4jSecurityInterceptor.setSecurementPassword(password);
    wss4jSecurityInterceptor.setSkipValidationIfNoHeaderPresent(true);
    wss4jSecurityInterceptor.setValidateRequest(false);
    wss4jSecurityInterceptor.setValidateResponse(false);
    return wss4jSecurityInterceptor;
}

private HttpComponentsMessageSender createMessageSender(String proxyHost, String proxyPort) {
    HttpComponentsMessageSender httpComponentsMessageSender = new HttpComponentsMessageSender(createHttpClient(proxyHost, proxyPort));
    httpComponentsMessageSender.setAcceptGzipEncoding(true);
    return httpComponentsMessageSender;
}

private HttpClient createHttpClient(String proxyHost, String proxyPort) {
    RequestConfig.Builder configBuilder = RequestConfig.custom()
            .setConnectTimeout(DEFAULT_CONNECTION_TIMEOUT_MILLISECONDS)
            .setSocketTimeout(DEFAULT_READ_TIMEOUT_MILLISECONDS)
            .setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT);
    addProxySettings(configBuilder, proxyHost, proxyPort);

    HttpClientBuilder clientBuilder = HttpClients.custom().setDefaultRequestConfig(configBuilder.build());
    addInterceptor(clientBuilder);
    addConnectionManager(clientBuilder);
    return clientBuilder.build();
}

private void addProxySettings(RequestConfig.Builder configBuilder, String proxyHost, String proxyPort) {
    if (StringUtils.isNotBlank(proxyHost)) {
        configBuilder.setProxy(new HttpHost(proxyHost, Integer.valueOf(proxyPort)));
    }
}

private void addInterceptor(HttpClientBuilder clientBuilder) {
    clientBuilder.addInterceptorFirst(new HttpComponentsMessageSender.RemoveSoapHeadersInterceptor());
}

private void addConnectionManager(HttpClientBuilder clientBuilder) {
    if (maxConnections > DEFAULT_MAX_CONNECTIONS_PER_ROUTE) {
        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
        cm.setMaxTotal(maxConnections);
        cm.setDefaultMaxPerRoute(maxConnections);
        clientBuilder.setConnectionManager(cm);
    }
}

This configuration worked fine for other soap implementations. But here I just get the soap envelope with the empty body.

Has anyone an idea what's wrong here?


Solution

  • I did something wrong when refactoring the LoggingInterceptor. When handling the request it took the response part from the MessageContext instead of the request part, which caused to overwrite the request with the response. So if you have such a problem check your interceptors if they handle response and request correctly