Пример интеграции с 1С через custom API
Материал из BiTel WiKi
Содержание |
Вступление
Для интеграции с внешними системами в BGBilling используется custom API. 1С очень чувствительна к структуре XML (XML Schema). Все должно находиться в корректных namespace и т.д. и т.п.. Так, если на первый взгляд биллинг возвращает корректную XML, то 1С может выдавать ошибки вида
Ошибка при вызове метода контекста (GetAgentList) ............ по причине: Ошибка вызова операции сервиса: {http://1c.billing.ru/}:TestImplService:GetAgentList() по причине: Неизвестная ошибка. Ошибка преобразования данных XDTO:
Для тестирования и отладки веб сервиса возможно использовать проверку сервисов через SoapUI.
Примеры динамических классов
Сам веб сервис
package api.ru.ellco.bgbilling.service.impl; import ru.bitel.bgbilling.kernel.container.service.server.AbstractService; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; import javax.xml.bind.annotation.XmlSeeAlso; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @WebService(name = "ServiceFor1CImpl", targetNamespace = "http://1c.billing.ru/") @XmlSeeAlso({ Agent1C.class, GetAgentListResponse.class }) public class ServiceFor1CImpl extends AbstractService { @WebMethod(operationName = "GetAgentList", action = "http://1c.billing.ru/GetAgentList") @WebResult(name = "GetAgentListResult", targetNamespace = "http://1c.billing.ru/") public GetAgentListResponse.GetAgentListResult getAgentList( @WebParam(name = "fc", targetNamespace = "http://1c.billing.ru/") String fc ) { Connection con = getConnection(); GetAgentListResponse.GetAgentListResult result = new GetAgentListResponse.GetAgentListResult(); String query = " SELECT c.id, c.title, c.comment, cp.val, (SELECT GROUP_CONCAT(id) FROM contract WHERE scid = c.id) as subList, mv.title " + " FROM contract AS c " + " LEFT JOIN contract_parameter_type_1 AS cp ON c.id = cp.cid AND cp.pid = 32 " + " LEFT JOIN contract_parameter_type_7 AS m ON m.cid = c.id AND m.pid = 27 " + " LEFT JOIN contract_parameter_type_7_values AS mv ON mv.id = m.val " + " WHERE c.fc = 1 " + " AND cp.val NOT LIKE '%не выгр%' " + " AND cp.val NOT LIKE 'закрыт' " + " AND c.scid <= 0 " + " ORDER BY c.id " + " LIMIT 10 "; try{ PreparedStatement ps = con.prepareStatement(query); ResultSet rs = ps.executeQuery(); while(rs.next()){ String cid = rs.getString("c.id"); String title = rs.getString("c.title"); String comment = rs.getString("c.comment"); String agentContractCode = rs.getString("cp.val"); String subList = rs.getString("subList"); String manager = rs.getString("mv.title"); Agent1C agent = new Agent1C(); agent.setContractId(cid); agent.setContractTitle(title); agent.setContractComment(comment); agent.setAgentContractCode(agentContractCode); agent.setSubList(subList); agent.setManager(manager); result.getAgents().add(agent); } } catch (SQLException e) { e.printStackTrace(); } return result; } }
package api.ru.ellco.bgbilling.service.impl; import javax.xml.bind.annotation.*; import java.util.ArrayList; @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = {"getAgentListResult"}, namespace = "http://1c.billing.ru/") @XmlRootElement(name = "GetAgentListResponse", namespace = "http://1c.billing.ru/") public class GetAgentListResponse { @XmlElement(name = "GetAgentListResult") protected GetAgentListResponse.GetAgentListResult getAgentListResult; @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = {"agents"}) public static class GetAgentListResult { @XmlMixed @XmlAnyElement(lax = true) protected ArrayList<Agent1C> agents; public ArrayList<Agent1C> getAgents() { if (agents == null) { agents = new ArrayList<Agent1C>(); } return this.agents; } } }
Описание Agent1C
package api.ru.ellco.bgbilling.service.impl; import javax.xml.bind.annotation.*; @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "", propOrder = {"contractId", "contractTitle", "contractComment", "agentContractCode", "subList", "manager"}, namespace = "http://1c.billing.ru/") @XmlRootElement(name = "Agent1C", namespace = "http://1c.billing.ru/") public class Agent1C { @XmlElement(name = "ContractId") protected String contractId; @XmlElement(name = "ContractTitle") protected String contractTitle; @XmlElement(name = "ContractComment") protected String contractComment; @XmlElement(name = "AgentContractCode") protected String agentContractCode; @XmlElement(name = "SubList") protected String subList; @XmlElement(name = "Manager") protected String manager; public String getContractId() { return this.contractId; } public void setContractId(String value) { this.contractId = value; } public String getContractTitle() { return this.contractTitle; } public void setContractTitle(String value) { this.contractTitle = value; } public String getContractComment() { return this.contractComment; } public void setContractComment(String value) { this.contractComment = value; } public String getAgentContractCode() { return this.agentContractCode; } public void setAgentContractCode(String value) { this.agentContractCode = value; } public String getSubList() { return this.subList; } public void setSubList(String value) { this.subList = value; } public String getManager() { return this.manager; } public void setManager(String value) { this.manager = value; } }
Добавление в 1С
Процедура КнопкаВыполнитьНажатие(Кнопка) ОпределениеПрокси = new WSОпределения("http://10.0.6.152/bgbilling/api/ru.ellco.bgbilling.service/ServiceFor1C?wsdl"); Прокси = new WSПрокси(ОпределениеПрокси, "http://1c.billing.ru/", "ServiceFor1CImplService", "ServiceFor1CImplPort"); //Создаем тип параметра. В тестовом варианте параметр не используется со стороны вебсервиса ТипWSПараметра = Прокси.ФабрикаXDTO.Пакеты.Получить("http://1c.billing.ru/").Получить("GetAgentList"); //Создаем параметр на основе типа и заполняем его значение. WSПараметр = Прокси.ФабрикаXDTO.Создать(ТипWSПараметра); WSПараметр.fc = "1"; ОчиститьСообщения(); //Вызываем метод веб-сервиса, записываем результат в переменную КурсыВалют. СписокАгентов = Прокси.GetAgentList(WSПараметр); Для Каждого Элемент Из СписокАгентов.GetAgentListResult.Agent1C Цикл Сообщить("ContractId = " + Элемент.ContractId + "; ContractTitle = " + Элемент.ContractTitle + "; ContractComment = " + Элемент.ContractComment); КонецЦикла; КонецПроцедуры
Выглядеть будет как-то так. Красным выделены значения которые вернулись пустыми. Обсуждение на форуме. Есть маленькая проблема с формированием XML, и необходимостью дополнительных проверок. Но на то он и пример, что не все до конца допилено.
Заключение
По вопросам и предложениям просьба отписывать в теме на форуме