2016-07-20 4 views
1

Я хочу создать клиент веб-сервиса SOAP весной с настраиваемыми учетными данными. Такая же реализация будет использоваться для вызова разных клиентов с различной аутентификацией пользователя/пароля. Будет использоваться обычная аутентификация.Spring WebServiceClient с настраиваемыми учетными данными

Как и для spring ws WebServiceTemplate credentials, но с разными учетными данными для каждого звонка.

Есть ли лучший способ сделать это, чем получить 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 Service Client

public Status updateStatus(URL url, String user, String password,PackageStatus request){ 
    WebServiceTemplate template = getWebServiceTemplate(); 
    //TODO set credentials here ??? 
    return (Status) template.marshalSendAndReceive(request); 
} 

Большое спасибо за вашу помощь, Neo

ответ

2

Наиболее общим решением является создание регулярной Класс фабрики Java, который будет создавать шаблон веб-сервиса учитывая полномочия. Ниже приведен пример, который использует 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; 
    } 
} 

Это самое основное решение, которое я вижу. Вы можете оптимизировать его, не создавая отдельный клиент для того же имени пользователя. Возможно, у вас также может быть один клиент для всех - проверьте документацию Apache HttpComponents (или документацию другого используемого клиента).

Обратите внимание, что Spring-WS не реализует клиента сам по себе, это всего лишь оболочка над некоторым существующим HTTP-клиентом.

Обновление:
Если вы используете Apache HttpClient, проверьте их использование AuthScope. Вы можете создать один HttpClient для всех получателей (хост, порт), каждый из которых имеет свою собственную пару имени пользователя/пароля. Но вы должны знать их заранее. Если это так, то приведенный выше код (модифицированный для установки пары AuthScope/credentials) может использоваться для создания регулярного компонента Spring. Правильная пара имени пользователя/пароля будет автоматически выбрана Apache HttpClient на основе адресата.

+0

Здравствуйте @Alexander это, кажется, хорошее решение с использованием фабрики. Не думал об этом. Спасибо за этот намек: D Использование AuthScope не будет возможным, так как во время исполнения добавляются и изменяются клиенты. Я дам фабрике попробовать сейчас. Благодаря! – NeoP5

+0

Добро пожаловать – Alexander