English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Pendant les vacances de la Qingming, j'ai revu les contenus pertinents du Web Service et ai fait un bref résumé de son principe de fonctionnement. Pour les amis qui en ont besoin et pour moi-même à l'avenir. Si l'article contient des erreurs, veuillez les suggérer pour que nous puissions nous encourager mutuellement.
Dans le service Web, nous devons d'abord comprendre le sens des termes pertinents : WSDL, UDDI... Une introduction aux termes pertinents n'est pas décrite ici, mais plutôt sur les principes.
Dans le service Web, il existe trois rôles : fournisseur de service, demandeur de service et médiateur de service, et leurs relations sont représentées comme suit1-1Indiqué
Mettre en œuvre un service Web complet implique les étapes suivantes :
◆ Le fournisseur de service Web conçoit et implémente le service Web, publie le service Web après le débogage correct via le médiateur de service Web et s'enregistre dans le centre d'enregistrement UDDI. (Publication)
◆ Le demandeur de service Web demande un service spécifique au médiateur de service Web, qui consulte le centre d'enregistrement UDDI pour trouver un service satisfaisant la demande pour le demandeur. (Discovery)
◆ Le médiateur de service Web renvoie aux demandeurs de service Web des informations de description de service Web qui répondent aux conditions, écrites en WSDL et lisibles par toutes les machines prenant en charge les services Web. (Discovery)
◆ Utilisez les informations de description retournées par le médiateur de service Web (WSDL) pour générer des messages SOAP correspondants et les envoyer au fournisseur de service Web pour appeler le service Web. (Liage)
◆ Le fournisseur de service Web exécute le service Web correspondant au message SOAP et renvoie le résultat du service au demandeur de service Web. (Liage)
Figure1-1 Architecture du service Web
Remarque : Le rôle de WSDL est celui d'une description de service Web. Le demandeur de service Web génère des messages SOAP correspondants en fonction de ce WSDL, et le fournisseur de service effectue le liage après avoir reçu le message de demande SOAP.
Le code suivant est une configuration de servlet dans web.xml
<!-- Lors de la définition des paramètres d'initialisation ou de l'URL personnalisée pour un servlet ou une page JSP, il est d'abord nécessaire de nommer le servlet ou la page JSP. L'élément Servlet est utilisé pour accomplir cette tâche. --> <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"); //获取输入流(相对于客户端来说,使用的是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()); //Écrit le message SOAP (par rapport au client, c'est out.write()) out.write(sb.toString().getBytes()); //Obtient la réponse du serveur int code = conn.getResponseCode(); if (code == 200) { InputStream is = conn.getInputStream(); byte[] b = new byte[1024]; int len = 0; soapOfResult = new StringBuffer(); //Lit un certain nombre de bytes à partir du flux d'entrée et les stocke dans le tableau de tampon b. Retourne le nombre de bytes effectivement lus sous forme d'entier //Si, en raison de la fin du fichier, il n'y a plus de bytes disponibles, la valeur de retour -1; while ((len = is.read(b)) != -1) { //Convertit le tableau de bytes en une chaîne en utilisant le charset nommé. String s = new String(b, 0, len, "UTF-8"); soapOfResult.append(s); } } conn.disconnect(); return soapOfResult == null ? null : soapOfResult.toString(); }
Remarque : après l'envoi d'un message de requête SOAP par le client, il est en état de blocage. Jusqu'à ce que le serveur renvoie le code d'état.
Ci-dessous est la réponse du serveur (enveloppe de réponse 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>
Après avoir reçu les données Json envoyées par le serveur, le client effectue les opérations d'analyse correspondantes. Voici par exemple :
// L'analyse du protocole SOAP (DOM parsing ne peut être utilisé que pour analyser les documents XML type, et les messages SOAP utilisent le format de données XML) Document doc = XmlUtil.string2Doc(result); Element ele = (Element) doc.getElementsByTagName("return").item(0); La chaîne utilisée dans la méthode2Corps de la méthode Doc() : public static Document string2Doc(String str) { //Convertir le document XML en arbre 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(); //Analyser le contenu du flux d'entrée donné en tant que document XML et retourner un nouveau Document DOM. document = build.parse(bais); } catch (Exception e) { e.printStackTrace(); } return document; }
Selon le résultat de retour, le client effectue une traitement approprié.
Voici les principes de base de fonctionnement des services Web.
Merci de lire, j'espère que cela peut aider tout le monde, merci pour le soutien de ce site !