Часто в работе нам необходимо логировать soap-сообщения: для отладки взаимодействия со сторонним сервисом или клиентом, для обращения в ТП и т.д. Если мы обратимся к официальной документации проекта Metro,
то там нам предложат воспользоваться системными свойствами для управления логированием.
Если кратко то, для серверной части веб-сервиса необходимо установить свойство
В результате вы увидите в логах сервера неотформатированный дамп SOAP-пакетов. И вроде все хорошо, но:
Каждый раз, копируя soap-сообщение из логов, приходится его вначале форматировать, а потом уже отправлять кому-либо или разбираться в струкртуре xml самому.Это не очень удобно и отнимает наше драгоценное время.
Как написано в документации проекта Metro, установка вышеперчисленных свойств в true, заставит glassfish печатать в System.out, а значит в логах log4j мы тоже ничего не увидим.
Итак, как же решить эти проблемы? Представляю вам класс MessageDumpingFeature из пакета com.sun.xml.ws.dump. Данный пакет можно найти в артефакте webservices-rt. Данную зависимость вы можете загрузить из maven репозитория добавив в свой pom.xml следующие строки:
<dependency>
<groupId>org.glassfish.metro</groupId>
<artifactId>webservices-rt</artifactId>
<version>2.3</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
Итак, зависимости загружены, можно приступать к написанию кода:
@WebServiceRef(wsdlLocation = "path/to/wsdl/file")
private SomeService serviceReference;
// Создаем объект logger
private final Logger logger =
LoggerFactory.getLogger(getClass().getName());
public void invokeServiceMethod(RequestData data){
//Создаем экземпляр класса MessageDumpingFeature
MessageDumpingFeature dumper = new MessageDumpingFeature();
//Получаем порт сервиса и передаем туда наш dumper
ServicePort port = service.getSomeServicePort(dumper);
//Отправляем какие-то данные в сервис и получаем ответ
Response responseFromService = port.sendData(data);
//логируем soap-request, вызвав метод nextMessage()
//nextMessage() возвращает xml в виде строки
logger.debug(dumper.nextMessage());
//логируем soap-response, вызвав метод nextMessage()
logger.debug(dumper.nextMessage());
Если кратко то, для серверной части веб-сервиса необходимо установить свойство
com.sun.xml.ws.transport.http.HttpAdapter.dump в true. Это можно сделать либо непосредственно в коде приложения:
System.setProperty(com.sun.xml.ws.transport.http.HttpAdapter.dump=true)
либо через параметры JVM:
-Dcom.sun.xml.ws.transport.http.HttpAdapter.dump=true
-
из кода:
System.setProperty(
com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true
)
- через парметр вирутальной машины: -Dcom.sun.xml.ws.transport.http.client.HttpTransportPipe.dump=true
В результате вы увидите в логах сервера неотформатированный дамп SOAP-пакетов. И вроде все хорошо, но:
- Для того чтобы включить логирование вам необходимо перезапустить сервер, что не всегда удобно и возможно.
- Вывод неотформатирован.
- А что если вы пользуетесь одной из реализаций SLF4J? (log4j вмоем случае)
Каждый раз, копируя soap-сообщение из логов, приходится его вначале форматировать, а потом уже отправлять кому-либо или разбираться в струкртуре xml самому.Это не очень удобно и отнимает наше драгоценное время.
Как написано в документации проекта Metro, установка вышеперчисленных свойств в true, заставит glassfish печатать в System.out, а значит в логах log4j мы тоже ничего не увидим.
Итак, как же решить эти проблемы? Представляю вам класс MessageDumpingFeature из пакета com.sun.xml.ws.dump. Данный пакет можно найти в артефакте webservices-rt. Данную зависимость вы можете загрузить из maven репозитория добавив в свой pom.xml следующие строки:
<dependency>
<groupId>org.glassfish.metro</groupId>
<artifactId>webservices-rt</artifactId>
<version>2.3</version>
<type>jar</type>
<scope>provided</scope>
</dependency>
Итак, зависимости загружены, можно приступать к написанию кода:
@WebServiceRef(wsdlLocation = "path/to/wsdl/file")
private SomeService serviceReference;
// Создаем объект logger
private final Logger logger =
LoggerFactory.getLogger(getClass().getName());
public void invokeServiceMethod(RequestData data){
//Создаем экземпляр класса MessageDumpingFeature
MessageDumpingFeature dumper = new MessageDumpingFeature();
//Получаем порт сервиса и передаем туда наш dumper
ServicePort port = service.getSomeServicePort(dumper);
//Отправляем какие-то данные в сервис и получаем ответ
Response responseFromService = port.sendData(data);
//логируем soap-request, вызвав метод nextMessage()
//nextMessage() возвращает xml в виде строки
logger.debug(dumper.nextMessage());
//логируем soap-response, вызвав метод nextMessage()
logger.debug(dumper.nextMessage());
}
Ну вот и все. Теперь разворачиваем приложение на сервере и смотрим отформатированные дампы soap-сообщений в логах log4j.
Комментариев нет:
Отправить комментарий