2016-05-09 2 views
0

Во время интеграции с внешней системой мне пришлось переключаться с одной среды на другую. Это означает изменение URL-адреса, в котором размещен wsdl, и размещение учетных данных пользователя в заголовке. Выглядит довольно легко, но потом я заметил странное поведение. При попытке вызова A, который находится на порту 1, то по какой-то причине заголовок SOAPAction заменяется значением обслуживания B, который также находится на порту 1. Это выглядит что-то вроде:Заголовок SOAPAction не соответствует службе

ID: 496 
Address: https://domain/env/port 
Encoding: UTF-8 
Http-Method: POST 
Content-Type: text/xml 
Headers: {Accept=[*/*], password=[test], SOAPAction=["serviceB"], UserName=[test]} 
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><a:aRequest xmlns:a="http://a/namespace/">... 

Тогда ответ конечно, что объект неожиданного запроса был передан. Что более странно, что иногда заголовок SOAPAction в порядке, вызванная служба в порядке, а объект запроса в порядке, но ответ по-прежнему говорит о том, что он ожидал другого объекта запроса, потому что по какой-то причине сервер вызывал другую службу, которую я хотел вызов.

Так что мой вопрос: каким образом задано значение SAOPAction - взято ли оно из сгенерированного класса из @WebMethod(action = "serviceA") или создается ли оно во время чтения wsdl-файла? Мне нужно выяснить это, если проблема на моей стороне или на стороне внешнего сервера.

EDIT: Я заметил, что: когда я вызываю serviceA в первый раз, тогда заголовок SOAPAction устанавливается в режим работы B. Затем я вызываю второй раз, когда serviceA и код ответа 200. Затем я вызываю serviceB в первый раз, а заголовок SOAPAction устанавливается в serviceA. Когда я вызываю serviceB во второй раз, тогда код ответа составляет 200. Таким образом, похоже, что есть какой-то кеширование (?!) ...

EDIT: Итак, это выглядит так: я создаю порт с классом обслуживания из пакета javax.xml.ws с методом Service myservice = Service.create(serviceName) и myservice.getPort(MySpecifiedPort.class). Я комментирую этот метод с помощью @Produces, и если мне нужен этот порт, я добавляю его аннотацией @Inject. Иногда я получаю (я думаю) экземпляр из пула. И если это произойдет, то SOAPAction будет установлено значение из предыдущего вызова. Но почему это происходит? Разве SOAPAction не должен устанавливаться как новый каждый раз, когда я вызываю WS? Кажется, что это похоже на кеширование?

ответ

0

Наконец, я надеюсь, что нашел решение. Проблема заключалась в том, что для того, чтобы установить заголовки HTTP с учетными данными я сделал:

Map<String, List<String>> headers = (Map<String, List<String>>) bp.getRequestContext().get(MessageContext.HTTP_REQUEST_HEADERS); 
if (headers == null) { 
    headers = new HashMap<>(); 
} 
headers.put("UserName", Collections.singletonList(configuration.getProperty(API_USERNAME))); 
headers.put("password", Collections.singletonList(configuration.getProperty(API_PASSWORD))); 
bp.getRequestContext().put(MessageContext.HTTP_REQUEST_HEADERS, headers); 

По некоторым причинам это вызывает проблемы и заголовок SOAPAction были иногда вспоминали с предыдущего вызова. Решение состоит в том, чтобы реализовать SOAPHandler

class CredentialsHandler implements SOAPHandler<SOAPMessageContext> { 

    private Configuration configuration; 

    public CredentialsHandler(Configuration configuration) { 
     this.configuration = configuration; 
    } 

    @Override 
    public boolean handleMessage(SOAPMessageContext context) { 
     try { 
      Map<String, List<String>> headers = new HashMap<>(); 
      headers.put("UserName", Collections.singletonList(configuration.getProperty(API_USERNAME))); 
      headers.put("password", Collections.singletonList(configuration.getProperty(API_PASSWORD))); 
      context.put(MessageContext.HTTP_REQUEST_HEADERS, headers); 
     } catch (ConfigurationException e) { 
      throw new IllegalStateException("Configuration exception"); 
     } 

     return true; 
    } 
} 

И в том месте, где мои заголовки были добавлены положить следующую строку кода:

bp.getBinding().setHandlerChain(Collections.<Handler>singletonList(new CredentialsHandler(configuration))); 
Смежные вопросы