Подключение к Web-сервисам NAV из Java
Необходимые знания/навыки
Пожалуйста, вначале прочтите эту статью – чтобы получить разъяснение по поводу изменений сервера приложений для работы с NTML-аутентификацией, а также краткого описания сценария, которую я буду реализовывать в Java.
Ну еще, конечно, надо немного знать Java :-)
Версии и дистрибутивы
Java не поддерживает SPNEGO-протокол аутентификации, но имеется поддержка NTLM-аутентификации, так что вам придется настроить Web Services listener на ее использование.
Я скачал Java developer toolkit отсюда — http://www.java.com/en/download/manual.jsp и установил его в c:\sun – и убедился что пусть c:\sun\SDK\bin добавлен в переменную PATH.
wsimport – импорт WSDL
Чтобы Java могла видеть и использовать веб-сервисы я использую wsimport – для создания прокси-классов Java. Беру папку, делаю в ней две пустых (generated и source), дальше использую следующую команду:
C:\java>wsimport -d generated -s source http://localhost:7047/DynamicsNAV/WS/SystemService
В результате будет создана серия файлов .class в папке
C:\java\generated\schemas\dynamics\microsoft\nav\system
И набор исходных файлов в папке
C:\java\source\schemas\dynamics\microsoft\nav\system
Обратите внимание, что структура папок – это пространство именно веб-сервиса (namespace).
javac – компиляция программы
Предположим, я создаю тестовую программу в папке c:\java\test.java, тогда следующая команда скомпилирует ее:
c:\java>c:\sun\sdk\jdk\bin\javac -cp .;generated test.java
Будет создан c:\java\test.class, который можно запустить.
java – запуск программы
Команда для запуска java-класса выглядит так:
c:\java>c:\sun\sdk\jdk\bin\java -cp .;generated test
В общем, хватит про настройки – давайте программировать… :)
Аутентификация
По умолчанию, java поддерживает Windows Authentication и если класс запущен в контексте windows-пользователя, его права автоматически используются для аутентификации при обращении к web-сервисам NAV.
Если вам необходимы другие права (подключение под другим пользователем), необходимо создать класс, производный от Authenticator и переписать функцию getPasswordAuthentication примерно так:
public PasswordAuthentication getPasswordAuthentication() {
return (new PasswordAuthentication("domain\user", new char[] {'p','a','s','s','w','o','r','d'}));
}
}
А затем в классе самой первой командой должна быть следующая:
test.java
Прежде всего, несколько инструкций import. Не уверен, что они все нужны. Затем тело функции main():
import java.util.*;
import java.io.*;
import javax.xml.namespace.QName;
import schemas.dynamics.microsoft.nav.system.*;
import schemas.dynamics.microsoft.page.customer.*; <span style="font-family: Times New Roman;">
</span>
public class test {
public static void main(String[] args) {<span style="font-family: Times New Roman;">
</span>
// main program code<span style="font-family: Times New Roman;">
</span>
}
}
Вот основной код:
String baseURL = "http://localhost:7047/DynamicsNAV/WS/";
Следующий код позволяет вам подключиться к веб-сервисам Navision (system service) на Java и получить фирмы, доступные на сервере приложений:
QName systemServiceQName = new QName("urn:microsoft-dynamics-schemas/nav/system/", "SystemService");
SystemService systemService = new SystemService(systemServiceURL, systemServiceQName);
SystemServicePort systemPort = systemService.getSystemServicePort();
List<String> companies = systemPort.companies();
System.out.println("Companies:");
for(String company : companies) {
System.out.println(company);
}
String cur = companies.get(0);
Теперь у меня есть фирма, которую я буду использовать в cur следующим способом (создание URL для страницы Customer):
QName customerPageQName = new QName("urn:microsoft-dynamics-schemas/page/customer", "Customer_Service"); <span style="font-family: Times New Roman;">
</span>
System.out.println("\nURL of Customer page:" + customerPageURL.toString());
Затем я создаю Service Client к странице Customer Page:
CustomerPort customerPort = customerService.getCustomerPort();
И используя его, читаю данные по клиенту 10000 и вывожу его название:
System.out.println("\nName of Customer 10000:" + cust.getName());
Наконец, давайте наложим фильтр и считаем всех клиентов из Англии, имеющих склад RED или BLUE:
filter1.setField(CustomerFields.fromValue("Location_Code"));
filter1.setCriteria("RED|BLUE"); <span style="font-family: Times New Roman;">
</span>
CustomerFilter filter2 = new CustomerFilter();
filter2.setField(CustomerFields.fromValue("Country_Region_Code"));
filter2.setCriteria("GB");<span style="font-family: Times New Roman;">
</span>
List<CustomerFilter> filters = new ArrayList<CustomerFilter>();
filters.add(filter1);
filters.add(filter2); <span style="font-family: Times New Roman;">
</span>
System.out.println("\nCustomers in GB served by RED or BLUE warehouse:");
CustomerList customers = customerPort.readMultiple(filters, null, 0);
for (Customer c : customers.getCustomer()) {
System.out.println(c.getName());
} <span style="font-family: Times New Roman;">
</span>
System.out.println("\nTHE END"); <span style="font-family: Times New Roman;">
</span>
} catch(MalformedURLException e) {
} catch(UnsupportedEncodingException e) {
}
Все вышенаписанное выдаст нам в консоль (на моей машине с запущенной NAV 2009 SP1 W1):
Надеюсь, статья поможет вам в работе.
Удачи!
Оригинал можно прочитать здесь: http://blogs.msdn.com/b/freddyk/archive/2010/01/19/connecting-to-nav-web-services-from-java.aspx

Автор: Андрей Стрельников
В области Navision - с 2003 года. Профессиональные интересы: NAV, MS SQL, .NET, BPMN, IT-менеджмент. Предметная область: логистика, финансы, склады, 3PL.
Количество статей, опубликованных автором: 86.