English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Подробное руководство по принципам работы Web Service

     Во время清明节小长假, я освежил в памяти相关信息 о веб-сервисе и кратко总结了 его принцип работы. Это может быть полезно для друзей и myself в будущем. Если в статье есть ошибки, пожалуйста, дайте ценные советы, чтобы мы могли вместе учиться.

      В веб-сервисе мы должны сначала понять значение связанных терминов: WSDL, UDDI... Более подробное описание терминов не рассматривается, акцент делается на принципах.
В веб-сервисе существуют три роли: провайдер услуги, запрашивающий услугу и посредник, их отношения показаны на рис. 1-1

    Реализация полного веб-сервиса включает следующие шаги:

   ◆ Предоставляющий веб-сервис разработчик проектирует и реализует веб-сервис, а после отладки и проверки корректности публикует его через посредника веб-сервиса и регистрирует в UDDI-регистраторе; (публикация)

   ◆ Заявитель веб-сервиса запрашивает у посредника веб-сервиса определенный сервис, посредник выполняет запрос к центру регистрации UDDI, чтобы найти сервис, соответствующий запросу; (Обнаружение)

   ◆ Посредник веб-сервиса возвращает заявителю информацию о веб-сервисе, которая соответствует условиям, информация записана в WSDL и может быть прочитана любыми машинами, поддерживающими веб-сервисы; (Обнаружение)

   ◆ Используя информацию о веб-сервисе, возвращаемую посредником веб-сервиса (WSDL), создается соответствующее сообщение SOAP и отправляется поставщику веб-сервиса для вызова веб-сервиса; (Привязка)

   ◆ Поставщик веб-сервиса выполняет соответствующий веб-сервис по сообщениям SOAP и возвращает результат веб-заявителю. (Привязка)

  

Рис. 1-1 Архитектура веб-сервиса

     Примечание: Функция WSDL - это руководство по веб-сервису. Заявитель веб-сервиса создает соответствующие сообщения SOAP на основе этого WSDL, а поставщик услуг выполняет привязку после получения запроса SOAP.

     Следующий код является конфигурацией сервлета в файле web.xml

  <!-- При определении инициализационных параметров или настройке URL для сервлета или JSP-страницы сначала необходимо命名 сервлет или JSP-страницу. Элемент сервлета используется для выполнения этой задачи. -->
  <servlet>
  <servlet-name>UserService</servlet-name>
  <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
  <!-- Маркирует, загружается ли сервлет контейнером при запуске (инстанцируется и вызывается метод init(); значение больше нуля, чем меньше значение, тем выше приоритет сервлета, и он загружается раньше при запуске приложения). -->
  <load-on-startup>1</load-on-startup>
  </servlet>
  <!-- Сервер, как правило, предоставляет сервлету стандартный URL: http://host/webAppPrefix/servlet/ServletName. -->
   Но часто URL изменяется, чтобы сервлет мог получить доступ к инициализационным параметрам или easierely обрабатывать относительные URL. При изменении стандартного URL используется элемент servlet-mapping. -->
  <servlet-mapping>
   <servlet-name>UserService</servlet-name>
   <!-- Описывает URL по отношению к корневой директории веб-приложения. Значение элемента url-pattern должно начинаться с обратной косой черты (/). -->
   <url-pattern>/user</url-pattern>
  </servlet-mapping>
  Часть красного кода очень важна, она будет загружена соответствующий servlet при запуске веб-контейнера. Часть зеленого цвета представляет внешнюю интерфейс этой службы. Таким образом, можно найти соответствующий файл jax-ws.xml (как показано ниже)
  <endpoint name="UserPort" implementation="cn.ujn.service.UserService"
    url-pattern="/user">
  </endpoint>

    Далее это привязывается к соответствующему реализованному классу cn.ujn.service.UserService. Тело SOAP-запроса, отправляемого клиентом, содержит имя метода и информацию о параметрах, запрашиваемых клиентом.

    Ниже приведено клиентское封装енное сообщение SOAP (в формате Json для передачи данных на сервер) (SOAP Rerquest Envelope):

  <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://ujn.cn/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-  <soapenv:Body>
-  <q0:login>
     <arg0>{"username":"shq","password":"shq"}</arg0>
 </q0:login>
 </soapenv:Body>
 </soapenv:Envelope>

Ниже приведено вызов веб-службы через протокол SOAP1.1

/** 
* Вызов веб-службы через протокол SOAP1.1 
* 
* text/xml Это основано на протоколе soap1.1 
* 
* @param wsdl Путь к WSDL 
* @param method Название метода 
* @param namespace Пространство имен 
* @param headerParameters Параметры заголовка 
* @param bodyParameters Параметры тела 
* @param isBodyParametersNS Тело параметров имеет ли пространство имен 
* @return String 
* @throws Exception 
*/ 
public static String invokeBySoap11(String wsdl, String method, 
String namespace, Map<String, String> headerParameters, 
Map<String, String> bodyParameters, boolean isBodyParametersNS) 
throws Exception { 
StringBuffer soapOfResult = null; 
// Удаление ?wsdl, получение списка методов 
int length = wsdl.length(); 
wsdl = wsdl.substring(0, length - 5); 
// Создание экземпляра URL с помощью строки 
URL url = new URL(wsdl); 
// Создание подключения 
HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 
// Установка метода запроса 
conn.setRequestMethod("POST"); 
// Если планируется использовать URL-соединение для ввода, то установите флаг DoInput в true 
conn.setDoInput(true); 
// Если планируется использовать URL-соединение для вывода, то установите флаг DoOutput в true 
conn.setDoOutput(true); 
// В основном устанавливает атрибуты заголовка HTTPURLConnection запроса (K-V) 
conn.setRequestProperty("Content-Type", "text/xml;charset=utf-8"); 
// Получение входного потока (по отношению к клиенту, используется OutputStream) 
OutputStream out = conn.getOutputStream(); 
// Получение сообщения soap1.1 версии 
StringBuilder sb = new StringBuilder(); 
sb.append("<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"  
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" ") 
sb.append("xmlns:ns0=\"" + namespace + "\""); 
sb.append(">"); 
//拼装消息头 
if (headerParameters != null) { 
sb.append("<soap:Header>"); 
for (Entry<String, String> headerParameter : headerParameters 
.entrySet()) { 
sb.append("<ns0:"); 
sb.append(headerParameter.getKey()); 
sb.append(">"); 
sb.append(headerParameter.getValue()); 
sb.append("</ns0:"); 
sb.append(headerParameter.getKey()); 
sb.append(">"); 
} 
sb.append("</soap:Header>"); 
} 
//拼装消息体 
sb.append("<soap:Body><ns0:"); 
sb.append(method); 
sb.append(">"); 
// 输入参数 
if (bodyParameters != null) { 
for (Entry<String, String> inputParameter : bodyParameters 
.entrySet()) { 
if (isBodyParametersNS) { 
sb.append("<ns0:"); 
sb.append(inputParameter.getKey()); 
sb.append(">"); 
sb.append(inputParameter.getValue()); 
sb.append("</ns0:"); 
sb.append(inputParameter.getKey()); 
sb.append(">"); 
} else { 
sb.append("<"); 
sb.append(inputParameter.getKey()); 
sb.append(">"); 
sb.append(inputParameter.getValue()); 
sb.append("</"); 
sb.append(inputParameter.getKey()); 
sb.append(">"); 
} 
} 
} 
sb.append("</ns0:"); 
sb.append(method); 
sb.append("></soap:Body></soap:Envelope>"); 
//测试用 
System.out.println(sb.toString()); 
//写入SOAP消息(相对于客户端来说,使用的是out.write()) 
out.write(sb.toString().getBytes()); 
// Получает ответ сервера 
int code = conn.getResponseCode(); 
if (code == 200) { 
InputStream is = conn.getInputStream(); 
byte[] b = new byte[1024]; 
int len = 0; 
soapOfResult = new StringBuffer(); 
// Читает определенное количество байтов из потока ввода и хранит их в массиве буфера b. Возвращает количество фактически прочитанных байтов в виде целого числа 
// Если因为没有 доступных байтов в конце потока, то возвращается значение -1; 
while ((len = is.read(b)) != -1) { 
// Преобразует массив байтов в строку с использованием указанного набора символов.  
String s = new String(b, 0, len, "UTF-8"); 
soapOfResult.append(s); 
} 
} 
conn.disconnect(); 
return soapOfResult == null ? null : soapOfResult.toString(); 
} 

    Примечание: после отправки клиентом запроса SOAP запрос блокируется до получения сервером кода состояния.

    Ниже приведен ответ сервера (обертка ответа SOAP):

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
-<S:Body>
-<ns2:loginResponse xmlns:ns2="http://ujn.cn/">
 <return>1</return>
</ns2:loginResponse>
 </S:Body>
</S:Envelope>

    Клиент, получив данные JSON от сервера, выполняет соответствующие операции по разбору. Например:

// Разбор протокола SOAP (DOM-разбор используется только для разборки документов типа XML, а сообщения SOAP используют формат данных XML) 
Document doc = XmlUtil.string2Doc(result); 
Element ele = (Element) doc.getElementsByTagName("return").item(0); 
Метод中使用到的string2Doc() метод Körper如下: 
public static Document string2Doc(String str) { 
//将XML文档解析成DOM树 
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
Document document = null; 
DocumentBuilder build; 
if (str == null || str.equals("")) { 
return null; 
} 
try { 
InputStream bais = new ByteArrayInputStream(str.getBytes("UTF-8")); 
build = factory.newDocumentBuilder(); 
//Parse the content of the given InputStream as an XML document and return a new DOM Document object.  
document = build.parse(bais); 
} catch (Exception e) { 
e.printStackTrace(); 
} 
return document; 
} 

    На основе возвращенного результата клиент выполняет соответствующую обработку.

    的上文是web服务的基本工作原理。

    Спасибо за чтение, надеюсь, это поможет вам, спасибо за поддержку нашего сайта!

Основной курс
Давайте подберем для вас