Spring WS 正在生成空的 SOAP 信封

Spring WS is generating empty SOAP Envelop

我想用 Spring WS WebServiceTemplate 调用 SOAP 服务。我经常使用它,到目前为止它一直有效。但是现在我只得到一个空壳的肥皂信封:

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

我已经使用 JAXB Maven 插件创建了请求和响应 类。生成的源代码看起来与正在运行的服务完全一样。

示例:

@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;
  }
}

我用 marshallSendAndReceive 调用网络服务模板

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

我使用 java 配置 WebServiceTemplate:

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);
    }
}

此配置适用于其他 soap 实现。但是我这里只拿到了空壳的肥皂信封。

有人知道这里出了什么问题吗?

重构LoggingInterceptor时我做错了。在处理请求时,它从 MessageContext 获取响应部分而不是请求部分,这导致用响应覆盖请求。因此,如果您遇到此类问题,请检查您的拦截器是否正确处理响应和请求