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

Introducción detallada del principio de funcionamiento de Web Service

     Utilizando el descanso de la清明节, he repasado el contenido relacionado con el Web Service y he realizado una breve síntesis de su principio de funcionamiento. A disposición de los amigos y para referencias futuras. Si hay errores en el artículo, por favor proponga sugerencias valiosas para que todos podamos aprender juntos.

      En el servicio web, primero debemos entender el significado de los términos relevantes: WSDL, UDDI. No se volverá a mencionar aquí la introducción de términos relevantes, sino que se enfocará en el principio.
En el servicio web, existen tres roles: proveedor de servicios, solicitante de servicios y mediador de servicios, y las relaciones entre ellos se muestran en la figura1-1Mostrado

    Implementar un servicio web completo incluye los siguientes pasos:

   ◆ El proveedor del servicio web diseña e implementa el servicio web, publica el servicio web correctamente depurado a través del intermediario del servicio web y lo registra en el centro de registro UDDI. (Publicación)

   ◆ El solicitante del servicio web solicita un servicio específico al intermediario del servicio web, y el intermediario consulta el centro de registro UDDI para encontrar el servicio que cumple con la solicitud del solicitante. (Descubrimiento)

   ◆ El intermediario del servicio web devuelve la información de descripción del servicio web que cumple con los requisitos al solicitante del servicio web, que se escribe en WSDL y puede ser leído por cualquier máquina que soporte servicios web. (Descubrimiento)

   ◆ Genera el mensaje SOAP correspondiente utilizando la información de descripción devuelta por el intermediario del servicio web (WSDL) y lo envía al proveedor del servicio web para llamar al servicio web. (Conexión)

   ◆ El proveedor del servicio web ejecuta el servicio web correspondiente según el mensaje SOAP y devuelve el resultado del servicio al solicitante del servicio web. (Conexión)

  

Figura1-1 Arquitectura del servicio web

     Nota: El papel de WSDL es una hoja de descripción de servicio web. El solicitante del servicio web genera el mensaje SOAP correspondiente según este WSDL, y el proveedor del servicio realiza la conexión después de recibir el mensaje de solicitud SOAP.

     El siguiente código es la configuración de servlet en web.xml

  <!-- Al establecer parámetros de inicialización o personalizar URL para servlet o página JSP, es necesario nombrar primero el servlet o la página JSP. El elemento Servlet se utiliza para realizar esta tarea. -->
  <servlet>
  <servlet-name>UserService</servlet-name>
  <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
  <!-- 标记容器是否在启动的时候就加载这个servlet(实例化并调用其init()方法;正数的值越小,该servlet的优先级越高,应用启动时就越先加载 -->
  <load-on-startup>1</load-on-startup>
  </servlet>
  <!-- 服务器一般为servlet提供一个缺省的URL:http://host/webAppPrefix/servlet/ServletName。
   但是,常常会更改这个URL,以便servlet可以访问初始化参数或更容易地处理相对URL。在更改缺省URL时,使用servlet-mapping元素。 -->
  <servlet-mapping>
   <servlet-name>UserService</servlet-name>
   <!-- 描述了相对于Web应用的根目录的URL。url-pattern元素的值必须以斜杠(/)起始。 -->
   <url-pattern>/user</url-pattern>
  </servlet-mapping>
  红色代码部分很重要,会在Web容器启动的时候加载相应的servlet。绿色部分为该服务的外部接口。以此找到相应的jax-ws.xml文件(如下所示)
  <endpoint name="UserPort" implementation="cn.ujn.service.UserService"
    url-pattern="/user">
  </endpoint>

    进而绑定到相关的相应的实现类cn.ujn.service.UserService中。客户端发送的SOAP请求消息消息体body中包含有客户端所请求的方法名和参数信息。

    以下为客户端封装的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协议调用Web服务

/** 
* 通过SOAP1.1协议调用Web服务 
* 
* 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连接进行输出,则将DoInput标志设置为true 
conn.setDoOutput(true); 
//主要是设置HttpURLConnection请求头里面的属性(K-V) 
conn.setRequestProperty("Content",-Type", "text/xml; charset=utf-8"); 
//obtener flujo de entrada (en comparación con el cliente, se utiliza OutputStream) 
OutputStream out = conn.getOutputStream(); 
// obtener soap1.1mensaje de versión 
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=\"" + espacio de nombres + "\""); 
sb.append(">"); 
//armar cabecera del mensaje 
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>"); 
} 
//armar cuerpo del mensaje 
sb.append("<soap:Body><ns0:"); 
sb.append(method); 
sb.append(">"); 
// parámetros de entrada 
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>"); 
//prueba de uso 
System.out.println(sb.toString()); 
//Escribe el mensaje SOAP (para el cliente, se usa out.write())}} 
out.write(sb.toString().getBytes()); 
//Obtener la respuesta del servidor 
int code = conn.getResponseCode(); 
if (code == 200) { 
InputStream is = conn.getInputStream(); 
byte[] b = new byte[1024]; 
int len = 0; 
soapOfResult = new StringBuffer(); 
//Lee una cierta cantidad de bytes desde el flujo de entrada y los almacena en el array de búfer b. Devuelve el número real de bytes leídos en forma de entero 
//Si no hay bytes disponibles para leer debido al final del flujo de archivo, se devuelve el valor -1; 
while ((len = is.read(b)) != -1) { 
//Convierte el array de bytes en una cadena utilizando el conjunto de caracteres nombrado.  
String s = new String(b, 0, len, "UTF-8"); 
soapOfResult.append(s); 
} 
} 
conn.disconnect(); 
return soapOfResult == null ? null : soapOfResult.toString(); 
} 

    Nota: Después de que el cliente envía el mensaje de solicitud SOAP, se coloca en estado bloqueado. Hasta que el servidor devuelva el código de estado.

    A continuación se muestra la respuesta del servidor (SOPA Response Envelope):

<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>

    El cliente realiza operaciones de análisis correspondientes después de recibir los datos Json enviados por el servidor. Como sigue:

// Se realiza la análisis del protocolo Soap (DOM parsing solo se puede usar para analizar documentos de tipo XML, y los mensajes SOAP utilizan el formato de datos XML) 
Document doc = XmlUtil.string2Doc(result); 
Element ele = (Element) doc.getElementsByTagName("return").item(0); 
String utilizada en el método2Cuerpo del método Doc(): 
public static Document string2Doc(String str) { 
//Convertir el documento XML en un árbol 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"));-8")); 
build = factory.newDocumentBuilder(); 
//Parsear el contenido del InputStream proporcionado como un documento XML y devolver un nuevo objeto DOM Document.  
document = build.parse(bais); 
} catch (Exception e) { 
e.printStackTrace(); 
} 
return document; 
} 

    El cliente realiza el procesamiento correspondiente según el resultado devuelto.

    A continuación, se describe el principio básico de funcionamiento del servicio web.

    Gracias por leer, espero que pueda ayudar a todos, gracias por el apoyo a nuestro sitio!

Te gustará