English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Utilizzando le vacanze di Qingming, ho ripassato i contenuti relativi a Web Service, ho fatto una breve sintesi del suo principio di funzionamento. Per i amici che hanno bisogno e per me stesso in futuro. Se ci sono errori nel testo, prego gli amici di fare suggerimenti preziosi, per cercare di migliorarsi insieme.
Nel servizio web, dobbiamo prima comprendere il significato dei termini relativi: WSDL, UDDI... La presentazione dei termini pertinenti non sarà discussa di nuovo, il focus sarà sulla teoria.
Nel servizio web, ci sono tre ruoli: fornitore di servizi, richiedente di servizi e mediatore di servizi, le loro relazioni sono illustrate nella Figura 1-1
Implementare un servizio web completo include i seguenti passaggi:
◆ Fornitore di servizi web progettano e implementano servizi web, pubblicano i servizi web corretti dopo il debug attraverso il mediatore di servizi web e li registrano nel registro UDDI; (pubblicazione)
◆ Il richiedente del servizio Web richiede un servizio specifico al mediatore del servizio Web, il mediatore consulta il registro UDDI per trovare il servizio soddisfacente la richiesta per il richiedente. (Discover)
◆ Il mediatore del servizio Web restituisce le informazioni descrittive del servizio Web soddisfacente le condizioni al richiedente del servizio Web, che sono scritte in WSDL e possono essere lette da qualsiasi macchina che supporta i servizi Web. (Discover)
◆ Genera un messaggio SOAP corrispondente utilizzando le informazioni descrittive restituite dal mediatore del servizio Web (WSDL) e invia il messaggio SOAP al fornitore del servizio Web per chiamare il servizio Web. (Binding)
◆ Il fornitore del servizio Web esegue il servizio Web corrispondente al messaggio SOAP e restituisce il risultato del servizio al richiedente del servizio Web. (Binding)
Figura 1-1 Architettura del servizio Web
Nota: Il ruolo del WSDL è quello di una guida per il servizio Web. Il richiedente del servizio Web genera un messaggio SOAP corrispondente in base a questo WSDL, e il fornitore del servizio esegue il binding del servizio dopo aver ricevuto la richiesta SOAP.
Il seguente codice è una configurazione servlet nel file web.xml
<!-- Quando si definiscono parametri di inizializzazione o URL personalizzati per un servlet o una pagina JSP, è necessario prima dare un nome al servlet o alla pagina JSP. L'elemento servlet viene utilizzato per completare questa operazione. --> <servlet> <servlet-name>UserService</servlet-name> <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class> <!-- Indica se il container deve caricare questo servlet (istanziare e chiamare il metodo init()) all'avvio. Il valore positivo più piccolo ha la priorità più alta e il servlet viene caricato prima dell'avvio dell'applicazione. --> <load-on-startup>1</load-on-startup> </servlet> <!-- Il server fornisce di solito un URL predefinito al servlet: http://host/webAppPrefix/servlet/ServletName. --> Ma spesso si cambia questa URL per permettere al servlet di accedere ai parametri di inizializzazione o per gestire più facilmente gli URL relativi. Utilizzare l'elemento servlet-mapping per cambiare l'URL predefinito. --> <servlet-mapping> <servlet-name>UserService</servlet-name> <!-- Descrive l'URL relativa al percorso radice dell'applicazione Web. Il valore dell'elemento url-pattern deve iniziare con una barra (/). --> <url-pattern>/user</url-pattern> </servlet-mapping> La parte in rosso è molto importante, verrà caricato il relativo servlet durante l'avvio del container web. La parte in verde rappresenta l'interfaccia esterna del servizio. In questo modo è possibile trovare il file jax-ws.xml corrispondente (come mostrato di seguito): <endpoint name="UserPort" implementation="cn.ujn.service.UserService" url-pattern="/user"> </endpoint>
Successivamente, viene associato al relativo implementazione cn.ujn.service.UserService. Il messaggio di richiesta SOAP inviato dal client contiene il nome del metodo richiesto e le informazioni sui parametri.
Di seguito è riportato il corpo del messaggio SOAP encapsulato dal client (in formato JSON per la trasmissione dei dati al server) (SOAP Request 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>
Di seguito è illustrato il chiamata al servizio web tramite il protocollo SOAP 1.1
/** * Chiamata al servizio web tramite il protocollo SOAP 1.1 * * text/xml Questo è basato sul protocollo SOAP 1.1 * * @param wsdl Il percorso del WSDL * @param method Il nome del metodo * @param namespace Lo spazio di nomi * @param headerParameters I parametri dell'intestazione * @param bodyParameters I parametri del corpo * @param isBodyParametersNS Il parametro isBodyParametersNS indica se i parametri del corpo hanno uno spazio di nomi * @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; // Rimuovere ?wsdl per ottenere l'elenco dei metodi int length = wsdl.length(); wsdl = wsdl.substring(0, length - 5); // Creare un'istanza di URL con un parametro di stringa URL url = new URL(wsdl); // Creare la connessione HttpURLConnection conn = (HttpURLConnection) url.openConnection(); // Impostare il metodo della richiesta conn.setRequestMethod("POST"); // Se si intende utilizzare la connessione URL per l'input, impostare il flag DoInput su true conn.setDoInput(true); // Se si intende utilizzare la connessione URL per l'output, impostare il flag DoOutput su true conn.setDoOutput(true); // Principalmente impostare le proprietà (K-V) dell'intestazione della richiesta HttpURLConnection conn.setRequestProperty("Content-Type", "text/xml;charset=utf-8"); // Ottenere lo stream di input (rispetto al client, si utilizza OutputStream) OutputStream out = conn.getOutputStream(); // Ottenere il messaggio di versione 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(">"); //Assembla l'intestazione del messaggio 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>"); } //Assembla il corpo del messaggio sb.append("<soap:Body><ns0:"); sb.append(method); sb.append(">"); //Parametri di input 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>"); //Test System.out.println(sb.toString()); //Inserisce il messaggio SOAP (rispetto al client, utilizza out.write()) out.write(sb.toString().getBytes()); //Obtains the server's response int code = conn.getResponseCode(); if (code == 200) { InputStream is = conn.getInputStream(); byte[] b = new byte[1024]; int len = 0; soapOfResult = new StringBuffer(); //Reads a certain number of bytes from the input stream and stores them in the buffer array b. Returns the actual number of bytes read as an integer //If the return value is -1 because there are no available bytes at the end of the stream, then the return value is -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(); }
Note: After the client sends the SOAP request message, it is in a blocking state until the server returns the status code.
The following is the response envelope of the server (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>
After the client receives the Json data sent by the server, it will perform the corresponding parsing operations. For example:
// Parsing the Soap protocol (DOM parsing can only be used to parse XML document types, and SOAP messages are in the format of XML data). Document doc = XmlUtil.string2Doc(result); Element ele = (Element) doc.getElementsByTagName("return").item(0); Il corpo del metodo utilizzato contiene string2Doc() come segue: 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; }
In base al risultato di ritorno, il client esegue il trattamento corrispondente.
Di seguito è riportato il principio di funzionamento fondamentale dei servizi web.
Grazie per aver letto, spero che possa aiutarvi, grazie per il supporto al nostro sito!