Microsoft - уроды! Убедился в этом ещё раз на практике.
Встала передо мной задача вызова вэб сервисов Sharepoint'a из Java. Казалось бы что проще? w3c и иже с ними не просто так хлеб едят. Ан нет. Похоже Microsoft умело игнорирует все стандарты и придумывает свои. Забегая вперёд скажу что столкнулся с двумя нарушениями:
- какой то свой проприетарный формат задание schema.
- свой собственный utf-8 *_*
Итак вопросы интеграции Java клиентов с Sharepoint хотелось бы рассмотреть на простой задаче(дабы не забыть и может быть кому нить понадобиться):
необходимо из Java клиента добавить значение в List. List, выражаясь терминами Sharepoint'a это таблица. А "добавить значение в List" значит добавить строчку в таблицу.
Итак самое простое: добавление библиотек работы с web services для Java клиента. Используется первый axis. Потому что уже знаю как с ним работать и что ждать.
axis
axis
1.4
axis
axis-jaxrpc
1.4
org.codehaus.mojo
axistools-maven-plugin
wsdl2java
/_vti_bin/Lists.asmx?WSDL
com.mycompany
.
src/main/java
Далее выполнить таргет generate-sources для maven'a.
Теперь собственно вызов:
ListsLocator locator = new ListsLocator();
ListsSoap_BindingStub stub = (ListsSoap_BindingStub) locator.getListsSoap();
stub.setUsername(login);
stub.setPassword(password);
UpdateListItemsResponseUpdateListItemsResult result = stub.updateListItems("{C1E5A7FA-0705-49A4-849E-96A1C607BEAB}", updates);
Sharepoint по умолчанию требует авторизации. У нас он настроен так что ему достаточно простой Basic. Магическая строчка: {C1E5A7FA-0705-49A4-849E-96A1C607BEAB} не что иное как GUID листа. По идее можно каким то образом указать нормальное human-readable имя, но я бился долго и упорно, но никак не мог его узнать.
updates - это UpdateListItemsUpdates который содержит в себе массив MessageElement. По сути всё это является xml'ником. Вместо того чтобы описать структуру этого xml'ника в WSDL, Microsoft решила оставить нам, разработчикам, псевдо-свободу *_*
В итоге создание этого xml выглядит примерно следующим образом:
MessageElement elem = new MessageElement();
elem.setAttribute("OnError", "Return");
elem.setAttribute("ListVersion", "1");
elem.setQName(new QName("Batch"));
MessageElement newReleaseMethod = new MessageElement();
newReleaseMethod.setQName(new QName("Method"));
newReleaseMethod.setAttribute("ID", "1");
newReleaseMethod.setAttribute("Cmd", "New");
MessageElement id = new MessageElement();
id.setQName(new QName("Field"));
id.setAttribute("Name", "ID");
id.setValue("New");
MessageElement projectInfo = new MessageElement();
projectInfo.setQName(new QName("Field"));
projectInfo.setAttribute("Name", "_x041f__x0440__x043e__x0435__x04");
projectInfo.setValue("some value");
... заполнение других необходимых значений столбцов...
newReleaseMethod.addChild(id);
newReleaseMethod.addChild(projectInfo);
... добавление необходимых child-element'ов...
elem.addChild(newReleaseMethod);
Как несложно догадаться "_x041f__x0440__x043e__x0435__x04" это и есть тот самый Microsoft'овский utf-8. Я посовещался с духами и мы вместе решили что это наверное всё таки название столбца. Тут нужно кое что пояснить: у столбцов есть как displayed имя так и настоящее имя. При заведении столбца (field'a) эти имена совпадают. Дальше пользователи могут издеваться только над отображаемыми именами. В данном случае нас интересует его настоящее имя. Как его узнать? Без понятия. Можно посмотреть на url в web-части sharepoint'a, можно посмотреть какие запросы делает sharepoint на web server через какой нить http dumper.
И напоследок: есть такое поле с типом URL. Так вот для него вот это:
projectInfo.setValue("
http://bash.org.ru");
Будет возвращать ошибку вида: "ничего не знаю. ничего не получилось. попробуйте позже". Собственно зная Microsoft сложно надеятся что "позже" действительно поможет. Сношение с гуглом показало, что значение должно быть такое:
projectInfo.setValue("
http://bash.org.ru,");
Собственно такая явная вещь как установка запятой в конце нужна для того чтобы отделить URL от его Description, поскольку тип URL для Sharepoint значит именно эти две вещи одновременно.