English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Mit der opportunity des Qingming-Ferien, habe ich die relevanten Inhalte des Web Service noch einmal durchgearbeitet und eine kurze Zusammenfassung ihres Arbeitsprinzips vorgenommen. Für Freunde und mich selbst für die zukünftige Referenz. Wenn es in dem Artikel Unpassendes gibt, bitte Freunde um wertvolle Vorschläge, um gemeinsam voranzukommen.
In einem Web-Dienst sollten wir zunächst die Bedeutung der relevanten Begriffe verstehen: WSDL, UDDI ... Eine Einführung in die relevanten Begriffe wird hier nicht wiederholt, der Fokus liegt auf dem Prinzip.
In einem Web-Dienst gibt es drei Rollen: Diensteanbieter, Diensteanfrager und Dienstmediator, und ihre Beziehungen sind wie im Diagramm gezeigt1-1wie gezeigt
Die Implementierung eines vollständigen Web-Dienstes umfasst die folgenden Schritte:
◆ Der Web-Dienst-Anbieter entwirft und implementiert den Web-Dienst, veröffentlicht den nach der Fehlerbehebung korrigierten Web-Dienst über den Web-Dienst-Mediator und registriert ihn im UDDI-Registerzentrum; (Veröffentlichung)
◆ Der Web-Dienst-Anfrager fordert spezifische Dienste beim Web-Dienst-Mediator an, der auf der Grundlage der Anfrage den UDDI-Registerzentrum abfragt und den Anfrager Dienste sucht, die die Anforderungen erfüllen; (Entdeckung)
◆ Der Web-Dienst-Mediator gibt den Web-Dienst-Anfrager die beschreibenden Informationen der Web-Dienste zurück, die die Anforderungen erfüllen, und diese Informationen werden in WSDL geschrieben, die von verschiedenen Maschinen, die Web-Dienste unterstützen, gelesen werden können; (Entdeckung)
◆ Eine entsprechende SOAP-Nachricht wird auf Basis der beschreibenden Informationen des Web-Dienst-Mediators erstellt und an den Web-Dienst-Anbieter gesendet, um den Aufruf des Web-Dienstes zu realisieren; (Bindung)
◆ Der Web-Dienst-Anbieter führt den entsprechenden Web-Dienst gemäß der SOAP-Nachricht aus und gibt das Serviceresultat an den Web-Dienst-Anfrager zurück. (Bindung)
Abbildung1-1 Architektur des Web services
Hinweis: Die Funktion von WSDL ist eine Web-Dienstbeschreibung. Der Diensteanfrager generiert auf Basis dieses WSDL die entsprechenden SOAP-Nachrichten, und der Diensteanbieter bindet den Dienst nach Erhalt der SOAP-Anfrage-Nachricht.
Nachfolgender Code ist die Servlet-Konfiguration in web.xml
<!-- Bei der Festlegung von Initialisierungseinstellungen oder der Anpassung von URL für Servlet oder JSP-Seiten muss zunächst der Name des Servlets oder der JSP-Seite vergeben werden. Der Servlet-Element ist dazu da, diese Aufgabe zu erledigen. --> <servlet> <servlet-name>UserService</servlet-name> <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class> <!-- markiert, ob der Container den Servlet bereits bei der Startphase lädt (Instanziierung und Aufruf von init()-Methode; Eine positive Zahl bedeutet eine höhere Priorität des Servlets, das bei der Anwendungstart zuerst geladen wird --> <load-on-startup>1</load-on-startup> </servlet> <!-- Der Server bietet in der Regel dem Servlet eine Standard-URL an: http://host/webAppPrefix/servlet/ServletName. Oft wird jedoch diese URL geändert, um sicherzustellen, dass der Servlet auf Initialisierungsparameter zugreifen oder die Verarbeitung relativer URLs einfacher gestalten kann. Beim Ändern der Standard-URL wird der servlet-mapping-Element. --> <servlet-mapping> <servlet-name>UserService</servlet-name> <!-- beschreibt die URL relativ zum Root-Verzeichnis der Web-Anwendung. url-Der Wert des pattern-Elements muss mit einem Backslash (/)anfängt. --> <url-pattern>/user</url-pattern> </servlet-mapping> Der rote Codeabschnitt ist sehr wichtig, er lädt den entsprechenden Servlet bei der Startphase des Web-Containers. Der grüne Abschnitt ist die externe Schnittstelle dieses Dienstes. Finden Sie so die entsprechenden jax-ws.xml-Datei (wie folgt gezeigt): <endpoint name="UserPort" implementation="cn.ujn.service.UserService" url-pattern="/user"> </endpoint>
Dadurch wird auf die entsprechenden Implementierungsklasse cn.ujn.service.UserService gebunden. Der Nachrichteninhalt des von der Clientseitigen SOAP-Anfrage-Nachricht enthaltenen body enthält den Namen der angeforderten Methode und die Parameterinformationen.
Nachfolgend ist der von der Clientseitigen SOAP-Nachrichtenkapsel verpackte Nachrichteninhalt (in Json-Format für Datenübertragung mit dem Server) (SOAP Anfrage Kapsel):
<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 这是以soap为基础1.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()); //Schreibt die SOAP-Nachricht (im Vergleich zum Client wird out.write() verwendet) out.write(sb.toString().getBytes()); //Das Erhalten der Antwort des Servers int code = conn.getResponseCode(); if (code == 200) { InputStream is = conn.getInputStream(); byte[] b = new byte[1024]]; int len = 0; soapOfResult = new StringBuffer(); //Liest eine bestimmte Anzahl von Bytes aus dem Eingabestrom und speichert sie im Pufferarray b. Gibt die tatsächlich gelesenen Bytes als Integer zurück //Wenn aufgrund des Endes des Flusses im Datei keine verfügbaren Bytes mehr vorhanden sind, wird der Rückgabewert -1; while ((len = is.read(b)) != -1) { //Converts the byte array to a string using the named charset. String s = new String(b, 0, len, "UTF-8"); soapOfResult.append(s); } } conn.disconnect(); return soapOfResult == null ? null : soapOfResult.toString(); }
Anmerkung: Nachdem der Client die SOAP-Anfrage gesendet hat, befindet er sich im blockierten Zustand, bis der Server den Statuscode zurückgibt.
Nachfolgend ist die Antwort des Servers (SOAP 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>
Nachdem der Client die von der Server-Side gesendeten Json-Daten erhalten hat, führt er die entsprechenden Parsing-Operationen durch. Zum Beispiel:
// Die Soap-Protokoll wird analysiert (DOM-Parser kann nur zum Analysieren von XML-Dokumenttypen verwendet werden, während SOAP-Nachrichten das XML-Datenformat verwenden) Document doc = XmlUtil.string2Doc(result); Element ele = (Element) doc.getElementsByTagName("return").item(0); Methoden verwenden string2Doc() Methodenkörper wie folgt: public static Document string2Doc(String str) { //XML-Dokument in ein DOM-Baum verarbeiten 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(); //Verarbeite den Inhalt des angegebenen InputStream als XML-Dokument und gib ein neues DOM-Dokument zurück. document = build.parse(bais); } catch (Exception e) { e.printStackTrace(); } return document; }
Der Client führt basierend auf dem Rückgabewert die entsprechenden Maßnahmen durch.
Dies ist der grundlegende Arbeitsmechanismus von Web-Services.
Vielen Dank für das Lesen, ich hoffe, es hilft Ihnen, danke für die Unterstützung unseres Standorts!