Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 具有可配置凭据的SpringWebServiceClient_Java_Spring_Web Services_Soap_Basic Authentication - Fatal编程技术网

Java 具有可配置凭据的SpringWebServiceClient

Java 具有可配置凭据的SpringWebServiceClient,java,spring,web-services,soap,basic-authentication,Java,Spring,Web Services,Soap,Basic Authentication,我想在Spring中创建一个具有可配置凭据的SOAP web服务客户端。 相同的实现将用于调用具有不同用户/通过身份验证的不同客户。 将使用基本身份验证 与类似,但每个呼叫的凭据不同 有没有比每次都获取WebServiceMessageSender并设置凭据更好的方法? 如果我这样做,那么与其他客户并行完成的请求会发生什么情况 当前配置 @Bean public WebServiceTemplate webServiceTemplate(){ WebServiceTemplate tem

我想在Spring中创建一个具有可配置凭据的SOAP web服务客户端。 相同的实现将用于调用具有不同用户/通过身份验证的不同客户。 将使用基本身份验证

与类似,但每个呼叫的凭据不同

有没有比每次都获取WebServiceMessageSender并设置凭据更好的方法? 如果我这样做,那么与其他客户并行完成的请求会发生什么情况

当前配置

@Bean
public WebServiceTemplate webServiceTemplate(){
    WebServiceTemplate template = new WebServiceTemplate();
    template.setMessageSender(messageSender());
    return template;
}

@Bean
public HttpComponentsMessageSender messageSender(){
    HttpComponentsMessageSender sender = new HttpComponentsMessageSender();
    return sender;
}
Web服务客户端

public Status updateStatus(URL url, String user, String password,PackageStatus request){
    WebServiceTemplate template = getWebServiceTemplate();
    //TODO set credentials here ???
    return (Status) template.marshalSendAndReceive(request);
}
非常感谢您的帮助,
Neo

最通用的解决方案是创建一个常规的Java factory类,该类将在给定凭据的情况下创建web服务模板。下面是使用apache HttpComponents 4.3版的示例:

class WebServiceTemplateFactory {
    //@Autowired - all dependencies that don't change, such as WebServiceMessageFactory,  Marshaller etc.

    WebServiceTemplate createWebServiceTemplate(String user, String pwd) throws Exception {
            WebServiceTemplate webServiceTemplate = new WebServiceTemplate();

            //create the HTTP client 
            RequestConfig requestConfig = RequestConfig.custom().setStaleConnectionCheckEnabled(true).build(); //can set more stuff like connection timeout etc.
            SSLContext sslContext =  SSLContexts.custom().build();
            SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, null, null, SSLConnectionSocketFactory.STRICT_HOSTNAME_VERIFIER);
            BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
            credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(user, pwd));
            CloseableHttpClient httpClient = HttpClients.custom()
                    .setDefaultRequestConfig(requestConfig)
                    .setSSLSocketFactory(sslSocketFactory)
                    .setDefaultCredentialsProvider(credentialsProvider)
                    .addInterceptorFirst(new HttpComponentsMessageSender.RemoveSoapHeadersInterceptor()) //preventing 'org.apache.http.ProtocolException: Content-Length header already present' exception
                    .build();

            //create the message sender
            HttpComponentsMessageSender messageSender = new HttpComponentsMessageSender(httpClient);
            messageSender.afterPropertiesSet(); // just for consistency - not expecting much from this call

            webServiceTemplate.setMessageSender(messageSender);
            //... set the rest of dependencies, if needed
            return webServiceTemplate;
    }
}
这是我看到的最基本的解决方案。 您可以通过不为同一用户名创建单独的客户端来优化它。您也可以为所有这些组件使用一个客户机—查看ApacheHttpComponents文档(或您使用的其他底层客户机的文档)

请注意,SpringWS本身并没有实现客户机,它只是一些现有HTTP客户机上的包装器

更新:

如果您使用的是Apache HttpClient,请检查他们对AuthScope的使用情况。您可以为所有目的地(主机、端口)创建一个HttpClient,每个目的地都有自己的用户名/密码对。但你必须事先了解他们。如果是这种情况,那么可以使用上面的代码(修改为设置所有AuthScope/credentials对)来创建常规Springbean。Apache HttpClient将根据目标自动选择正确的用户名/密码对。

Hello@Alexander这似乎是一个很好的使用工厂的解决方案。我没想过。感谢您的提示:由于在运行时添加/修改了客户,因此不可能使用AuthScope创建D。我现在就去工厂试一试。谢谢