При интеграции сторонних приложений на Java с информационной базой 1С через механизм Web-сервисов (SOAP) разработчики часто сталкиваются с рядом типовых сложностей: удержание сеанса веб-сервером Apache, настройка авторизации пользователя и ошибки парсинга входящих/исходящих параметров метода. Разберем по шагам, как правильно настроить каждый из этих компонентов для стабильного взаимодействия систем.
В процессе вызова веб-сервиса веб-сервер (например, Apache или IIS) создает пул рабочих процессов для обслуживания входящих запросов. В файловых информационных базах активный сеанс веб-сервиса удерживает блокировку файла базы данных 1Cv8.1CD, что не позволяет выполнять монопольные операции или может создавать задержки при повторных обращениях. По умолчанию время удержания сеанса в пуле составляет 20 минут.
Проанализируем структуру конфигурационного файла публикации default.vrd. Чтобы веб-сервер быстрее завершал неактивные сеансы, добавим и настроим секцию pool внутри корневого узла публикации:
<point xmlns="http://v8.1c.ru/srd"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
base="/wsTest"
ib="File="C:\Bases\wsTest";">
<ws>
<point name="test" alias="test.1cws" enable="true"/>
</ws>
<pool size="10"
minSize="0"
maxAge="60"
lifeTime="120"/>
</point>
Рассмотрим подробнее параметры секции управления пулом:
0).Если в информационной базе 1С включен список пользователей и требуется аутентификация, передачу учетных данных необходимо настроить на стороне клиента. Использование глобального вызова Authenticator.setDefault() не рекомендуется, так как это затрагивает все исходящие HTTP-соединения виртуальной машины Java.
Посмотрим на пример безопасной настройки HTTP Basic-аутентификации через контекст порта JAX-WS:
import javax.xml.ws.BindingProvider;
import java.util.Map;
// Создаем экземпляр сервиса и получаем порт
wsTest service = new wsTest();
wsTestPortType port = service.getTestSoap();
// Приводим порт к BindingProvider для передачи заголовков
BindingProvider bindingProvider = (BindingProvider) port;
Map<String, Object> requestContext = bindingProvider.getRequestContext();
// Устанавливаем учетные данные пользователя 1С
requestContext.put(BindingProvider.USERNAME_PROPERTY, "admin");
requestContext.put(BindingProvider.PASSWORD_PROPERTY, "12345");
При добавлении параметров в операцию веб-сервиса на стороне 1С часто возникает исключение ServerSOAPFaultException: SOAP message parsing error: unknown parameter. Выясним причину этой проблемы.
В платформе 1С для параметров операций веб-сервиса задается свойство Направление:
Если параметр объявлен в 1С как Выходной, сервер не ожидает увидеть соответствующий XML-тег во входящем запросе. Если вручную объявить в Java-интерфейсе обычный строковый аргумент public String Take(String param1, String param2), клиент сериализует оба параметра в запрос, что приведет к ошибке разбора XML на стороне 1С.
Для корректной работы с выходными параметрами в JAX-WS применяется класс-обертка javax.xml.ws.Holder. Разберем правильный вариант вызова:
import javax.xml.ws.Holder;
// Входной параметр передается обычной строкой
String inputParam = "1234";
// Выходной параметр инициализируется объектом Holder
Holder<String> outputParam = new Holder<>();
// Вызываем операцию веб-сервиса
String result = port.take(inputParam, outputParam);
// Значение выходного параметра получаем из свойства value
String errorDescription = outputParam.value;
Чтобы избежать ошибок ручного описания структуры XML, рекомендуется генерировать классы клиента автоматически на основе WSDL-описания схемы 1С. Для этого используются встроенные средства IDE (NetBeans, IntelliJ IDEA, Eclipse) либо консольная утилита JDK wsimport.
Посмотрим на пример команды для генерации прокси-классов через консоль:
wsimport -keep -p com.example.wsclient -s ./src -encoding UTF-8 http://localhost/wsTest/ws/test.1cws?wsdl
Обратите внимание: если команда wsimport не распознается операционной системой, убедитесь, что путь к каталогу bin установленного JDK добавлен в системную переменную среды PATH. В версиях Java 11 и новее библиотеки JAX-WS вынесены из состава JDK, поэтому для современных проектов генерацию классов рекомендуется выполнять с помощью специализированных плагинов сборщиков Maven или Gradle (например, jaxws-maven-plugin).