在 Spring 中将超时设置为 WS https 调用 (HttpsUrlConnectionMessageSende



我正在尝试为 WS 调用设置超时。我延长了WebServiceGatewaySupport并尝试像这样设置为发件人超时:

public Object marshalSendAndReceive(Object requestPayload) {
        WebServiceTemplate wsTemplate = this.getWebServiceTemplate();
        for (WebServiceMessageSender sender : wsTemplate.getMessageSenders()) {
            try {
                HttpComponentsMessageSender httpSender = (HttpComponentsMessageSender) sender;
                httpSender.setReadTimeout(3000);
                httpSender.setConnectionTimeout(2000);
            } catch (ClassCastException | NumberFormatException cex) {
                logger.warn("Cannot set WS timeout: " + cex.getMessage());
            }
        }
        return wsTemplate.marshalSendAndReceive(requestPayload);
    }

(问题#6733744(

但是我得到:Cannot set WS timeout: org.springframework.ws.transport.http.HttpsUrlConnectionMessageSender cannot be cast to org.springframework.ws.transport.http.HttpComponentsMessageSender

是否可以以某种方式将

超时设置为HttpsUrlConnectionMessageSender?或者有没有其他方法可以在 spring-boot 中为 https ws 调用设置超时?

谢谢。

我遇到了同样的问题,并设法使用HttpComponentsMessageSender使其工作。这是我的代码:

HttpComponentsMessageSender messageSender = new HttpComponentsMessageSender();
HttpClient httpClient = HttpClientFactory.getHttpsClient(sslUtils, timeout);
messageSender.setHttpClient(httpClient);
webServiceTemplate.setMessageSender(messageSender);

我还创建了一个新的工厂类HttpClientFactory来设置 SSL 和超时:

import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContextBuilder;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
public class HttpClientFactory {
    private static CloseableHttpClient client;
    private HttpClientFactory() {
    }
    public static HttpClient getHttpsClient(SslUtils sslUtils, int timeout) throws Exception {
        if (client != null) {
            return client;
        }
        SSLContext sslcontext = getSSLContext(sslUtils);
        SSLConnectionSocketFactory factory = new SSLConnectionSocketFactory(sslcontext, new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        });
        HttpClientBuilder httpClientBuilder = HttpClients.custom();
        httpClientBuilder.addInterceptorFirst(new ContentLengthHeaderRemover());
        RequestConfig config = RequestConfig.custom()
                                    .setConnectTimeout(timeout)
                                    .setConnectionRequestTimeout(timeout)
                                    .setSocketTimeout(timeout)
                                    .build();
        return httpClientBuilder.setSSLSocketFactory(factory)
                    .setDefaultRequestConfig(config)
                    .build();
    }
    private static class ContentLengthHeaderRemover implements HttpRequestInterceptor {
        @Override
        public void process(HttpRequest request, HttpContext context) throws HttpException, IOException {
            request.removeHeaders(HTTP.CONTENT_LEN);
        }
    }
    public static void releaseInstance() {
        client = null;
    }
    private static SSLContext getSSLContext(SslUtils sslUtils) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, KeyManagementException {
        KeyStore ks = KeyStore.getInstance("JKS");
        ks.load(sslUtils.getKeystore().getInputStream(), sslUtils.getKeyPwd().toCharArray());
        sslUtils.getKeystore().getInputStream().close();
        KeyStore ts = KeyStore.getInstance("JKS");
        ts.load(sslUtils.getTrustStore().getInputStream(), sslUtils.getTrustPwd().toCharArray());
        sslUtils.getTrustStore().getInputStream().close();
        SSLContextBuilder sslContextBuilder = SSLContexts.custom();
        try {
            sslContextBuilder = SSLContexts.custom().loadKeyMaterial(ks, ssl.getKeyPwd().toCharArray());
        } catch (UnrecoverableKeyException e) {
            e.printStack();
        }
        sslContextBuilder.loadTrustMaterial(ts, new TrustSelfSignedStrategy());
        return sslContextBuilder.build();
    }
}

有关信息,SslUtils 只是一个保存密钥库和信任库信息的 Bean 类:

public class SslUtils {
    private Resource keystore;
    private String keyPwd;
    private Resource trustStore;
    private String trustPwd;
    // Getters and Setters
}

这对我有用,让我同时使用 SSL 和超时。我希望这将帮助其他人。

您收到强制转换异常,因为 HttpsUrlConnectionMessageSender 和 HttpComponentsMessageSender 不是兼容的类型。它们都共享同一个超类(WebServiceMessageSender(,但不能将一个强制转换为另一个。我认为您可以在WebServiceTemplate配置中使用HttpComponentsMessageSender。 请参阅如何在 Spring WebService Template 和 Spring WebServiceTemplate 连接超时属性中设置超时

相关内容

  • 没有找到相关文章

最新更新