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

تفصيل مبدأ تشغيل Web Service

     باستخدام عطلة عيد العمال، تم مراجعة محتويات خدمة الويب، وتلخيص عملها الأساسي. لاستخدام الأصدقاء والأصدقاء والاستخدام الذاتي في المستقبل. إذا كان هناك أي خطأ في المقال، يرجى تقديم نصائح قيمة من الأصدقاء، للحفاظ على التشجيع المتبادل.

      في خدمات الويب، يجب علينا أولاً فهم معاني المصطلحات ذات الصلة: WSDL، UDDI،... لا يتم الحديث عن هذا الموضوع بعد الآن، ولكن يتم التركيز على المبادئ.
في خدمات الويب، هناك ثلاثة أدوار: المزود بالخدمة، طالب الخدمة، ووسيط الخدمة، والعلاقات بينهم كما هو موضح في الشكل 1-1

    تحقيق خدمة ويب كاملة يشمل الخطوات التالية:

   ◆ المزودون بخدمات الويب يصممون ويقومون بتنفيذ خدمات الويب، ويقومون بنشر خدمات الويب التي تم إصلاحها بشكل صحيح من خلال وسيط خدمات الويب، ويرجعونها إلى مركز التسجيل UDDI؛ (النشر)

   ◆ Web服务请求者向Web服务中介者请求特定的服务,中介者根据请求查询UDDI注册中心,为请求者寻找满足请求的服务;(发现)

   ◆ Web服务中介者向Web服务请求者返回满足条件的Web服务描述信息,该描述信息用WSDL写成,各种支持Web服务的机器都能阅读;(发现)

   ◆ 利用从Web服务中介者返回的描述信息(WSDL)生成相应的SOAP消息,发送给Web服务提供者,以实现Web服务的调用;(绑定)

   ◆ Web服务提供者按SOAP消息执行相应的Web服务,并将服务结果返回给Web服务请求者。(绑定)

  

图1-1 Web service的体系结构

     注:WSDL的作用就是一个Web服务说明书。服务请求者根据此WSDL生成相应的SOAP消息,服务提供者在收到SOAP请求消息后,进行服务的绑定。

     以下代码是在web.xml中的servlet配置

  <!--在向servlet或JSP页面制定初始化参数或定制URL时,必须首先命名servlet或JSP页面。Servlet元素就是用来完成此项任务的。--->
  <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>
  جزء الأحمر مهم، سيتم تحميل servlet المحدد عند بدء Web Container. الجزء الأخضر هو واجهة الخدمة الخارجية. بهذا يمكن العثور على ملف 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 للإخراج، فقم بتعيين راية DoInput إلى true 
conn.setDoOutput(true); 
// يهدف إلى تعيين خصائص رأس الـHttpURLConnection (مفتاح-قيمة) 
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) { 
// يحول مصفوفة البايتات إلى نص باستخدام charset المسمى.  
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() كما يلي: 
public static Document string2Doc(String str) { 
//Convert XML document to DOM tree 
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; 
} 

    بناءً على النتيجة المقدمة، يقوم العميل بمعالجة مناسبة.

    هذا هو المبدأ الأساسي للعمل للخدمات الويب.

    شكرًا على قراءتك، آمل أن تكون مفيدًا لك، شكرًا لدعمك للموقع!

أنت قد تستمتع بهذا