Некоторые способы взаимодействия Java с 1С
Часть 2. Web – services. 1C server – Java client
Данная статья посвящена интеграции Java и 1С c помощью технологии Web- сервисов. Задача, которая была решена с помощью данной технологии - обеспечение возможности получения бухгалтерской информации (обороты и остатки) из 1С в ряде технических задач реализованных с помощью Java – технологий. Реализация возможности обмена информацией с помощью Web – сервисов подразумевает следующий комплекс мероприятий:
- Создание серверной части Web – сервиса на 1С
- Настройка Web-сервера Apache для взаимодействия с 1C
- Создание клиентской части Web – сервиса средствами Java.
Прежде чем приступить к описанию этапов реализации, рассмотрим более подробно возможные способы взаимодействия самих Java – программ с Web – сервисом. Безусловно, самым простым способом является создание непосредственно на самом Swing клиенте Web-service (client), однако мы посчитали что это будет нецелесообразно по следующим причинам: во-первых сильно "утяжеляется" клиент, так как ему необходимы библиотеки для работы с сервисом, в частности JAX-WS 2.1, во-вторых, вся бизнес логика обработки результатов будет выполняться на пользовательской машине; в-третьих, разные приложения используют одни и те же сервисы, в четвертых Java – клиент реализован как в виде Swing – приложений, так в виде Web – приложений. Поэтому было принято решение, реализовать все сервисы в Web приложении, которое функционирует в контейнере сервлетов – Tomcat 6.014, для доступа к Web - сервисам использовать непосредственно сами сервлеты, которые можно вызывать из любого приложения. Кроме того, данное решение сильно облегчило процесс отладки приложения, так как вызов сервиса заключался в вводе URL, ни как не затрагивая Java клиентов.
Следует заметить, что процесс разработки составил примерно 10% времени от общего времени выполнения задачи, остальное время заняло тестирование и отладка.
На первом этапе при реализации серверной части Web – сервиса на 1С необходимо было выполнить следующее:
- Описать XDTO пакет
- Реализовать прием входных параметров, их обработку и возврат клиенту
В "1С Предприятии v8" XDTO пакеты служат для описания типов параметров возвращаемых web-сервисами.
Как и в случае Java - клиентской части, отладка заняла большую часть времени, всего процесса разработки web-сервиса. Из проблем, с которыми пришлось столкнуться, можно отметить следующие:
1. Настройка режима отладки "1С Предприятия 8" при тестировании Web-сервиса; 2. При прохождении синтаксического анализа в конфигураторе при отладке не определялся ряд ошибок, которые затем обнаруживались при выполнении в нормальном режиме.; 3. При отладке на локальной машине под управлением ОС Windows Vista после отработки запроса web-сервисом приходилось постоянно перезапускать Web - сервер Apache 2.2, так как в противном случае запрос не воспринимался,Второй этап заключался в установке Web-server-a Apache, особенность данного этапа является то, что в конфигурационном файле httpd.conf необходимо прописать путь к библиотеки 1C, которая позволяет взаимодействовать с сервисом через Web-server:
LoadModule _1cws_module "C:/Program Files/1cv81/bin/wsapch2.dll"
Третий этап, подразумевает процесс создания Web-сервиса на стороне Java – клиента, что используя технологию JSR 224 и IDE NetBeans подробно описано в [1].
Рассмотрим более подробно процесс отладки, как было описано выше он занял 90% общего времени от начала разработки до ввода в эксплуатацию, надеемся это поможет многим избежать наших ошибок.
Напомним коротко архитектуру взаимодействия. Web-сервис 1С генерирует wsdl файл и размещает его на локальном сервере под ОС Windows. Клиентский сервис работает в рамках Web – приложения на сервере приложений Tomcat 6.0.14. в среде OC Debian 4.0. С программистами 1С, были оговорены структуры объектов – проводок, которые после выполнения определенных операций приводились к структуре Java бизнес-объектов, инкапсулировались в специальные объекты обертки (wrapper), которые используя библиотеку simple-xml 1.7.2 сериализовали коллекции xml. Для этих целей были реализованы сервлеты, в задачи которых входит, инициализация Web-сервиса, формирования запроса для них, получение результата и передача его на клиента, листинг 1.
Листинг 1. Фрагмент сервлета для получения оборотов по счетам.
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
OutputStream os = response.getOutputStream();
response.setContentType("text/xml;charset=UTF-8");
String id = null;
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy-HH.mm.ss");
Date begDate;
Date endDate;
GregorianCalendar grBeg =null;
GregorianCalendar grEnd =null;
HttpSession sess = request.getSession(true);
// номер договора
if (request.getParameter("id") != null) {
id = request.getParameter("id");
log.info("Запрос для договора - "+id);
}
//диапазон дат
if (request.getParameter("begDate") != null) {
begDate = sdf.parse(request.getParameter("begDate"));
grBeg = new GregorianCalendar();
grBeg.setTime(begDate);
}
if (request.getParameter("endDate") != null) {
endDate = sdf.parse(request.getParameter("endDate"));
grEnd = new GregorianCalendar();
grEnd.setTime(endDate);
}
// Инициализируем коллекцию проводок
List lsEnts = new ArrayList();
// Создаются временные коллекции аналитик которые
Map aMapdb = new HashMap();
Map aMapcr = new HashMap();
aMapcr.put("kau2", id);
long start = System.currentTimeMillis();
// Инициализация веб-сервисов
ru.rosten.to1c.Balance1C service = new ru.rosten.to1c.Balance1C();
ru.rosten.to1c.Balance1CPortType port = service.getBalance1CSoap();
// Начинаем вызывать веб сервисы
//1 - Деб 79.99 Кред 62.02.02 Кау2 = id - договора
for (SimpleEntry sient :
queryDB.getEntry1C(grBeg,grEnd,"79.99", "62.02.2",aMapdb, aMapcr, port )) {
lsEnts.add(sient.toEntry());
}
........................................................
.....................................................................
log.info("Количество проводок в базе 1С -"+lsEnts.size());
long end = System.currentTimeMillis();
log.info("Обрабокта на сервере 1С выполнена за " + (end - start) + " мс");
EntrySetWrapper esw=new EntrySetWrapper(lsEnts,1);
EntrySetWrapper.toXML(esw,os );
os.flush();
os.close();
} catch (Exception ex) {
log.error("Ошибка!!!!", ex);
}
}
Дальнейшее изложение будет построено следующим образом, будет приведена ошибка и возможные способы устранения.
- -
javax.xml.ws.WebServiceException: Failed to access the WSDL at: http://172.18.64.48/ws/balance1C.1cws?wsdl. It failed with:
Причина возникновения данной ошибки обусловлена тем, что доступ в папку, где располагается WSDL – файл, был разрешен только для пользователей Windows – домена, Решение - установить анонимный доступ к данному ресурсу;
Server returned HTTP response code: 500 for URL: http://172.18.64.48/ws/balance1C.1cws?wsdl. - -
2008-06-04 09:01:46,102 ERROR [ru.rosten.webutil.IExecHibernateQuery$QuerysDB] javax.xml.ws.WebServiceException: Failed to access the WSDL at: http://172.18.64.10/ws/balance1C.1cws?wsdl. It failed with:
На устранение данной ошибки было затрачено гораздо больше времени по сравнению с остальными. Связана она с тем, что 1C – Web – сервис, требовал авторизацию, и если при разработке и локальной отладке, данную проблему удалось легко решить, задав имя пользователя и пароль в настройках прокси – сервера в самой IDE. Но при вводе в опытную эксплуатацию она возникла вновь. Были предпринты несколько способов ее устранения. Путем установки системных параметров на сервере приложений:
Server returned HTTP response code: 401 for URL: http://172.18.64.10/ws/balance1C.1cws?wsdl.
System.getProperties().put("http.proxyHost", "center");
System.getProperties().put("http.proxyUser", "ws");
System.getProperties().put("http.proxyPassword", "apache");
Созданием связанного провадера:
BindingProvider bp = (BindingProvider) port;
bp.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "ws");
bp.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "apache");
Однако после всех наших длительных изысканий, нашими доблестными специалистами 1С была выявлена возможность задания данных параметров на стороне 1С в файле balance1C.1cws. - -
2008-06-05 13:24:09,498 ERROR [ru.rosten.webutil.IExecHibernateQuery$QuerysDB]
com.sun.xml.ws.server.UnsupportedMediaException: Unsupported Content-Type: text/xml; charset=utf-8 Supported ones are: [application/soap+xml]
Причиной данной ошибки заключалась в некорректных параметрах передаваемых на 1С. В силу того, что перевод работающего 1С сервера в режим отладки, является довольно проблематичной задачей, а так же того, что в 1С, отсутствуют такие великолепные механизмы логирования каким является например библиотека log4j, устранение ее заняло непозволительно долгий отрезок времени.
Будем признательны если кто –то поделится своими решениями и проблемами возникшими при аналогичной интеррации.
Список используемых источников
- Сайт разработчиков NetBeans http://www.netbeans.org/kb/60/websvc/jax-ws.html
П.В. Александров (ОТР, г. Ростов-на-Дону),
А.А. Коломоец (Портал – ЮГ, г.Краснодар)