خدمات ويب SOAP في جافا مثال باستخدام Eclipse

الخدمات الويب بالصابون في جافا يمكن تطويرها بعدة طرق. تعلمنا عن خدمات الويب بالصابون JAX-WS في البرنامج التعليمي السابق، واليوم سنتعلم كيفية إنشاء خدمة ويب بالصابون وبرنامج عميل لها باستخدام Eclipse. هنا لن نستخدم JAX-WS، بل سنستخدم Apache Axis الذي يتم دمجه في Eclipse ويوفر طريقة سريعة وسهلة لتحويل تطبيق إلى خدمة ويب جافا وإنشاء برنامج عميل بأقلام الاختبار مع صفحة JSP لأغراض الاختبار.

خدمات الويب بالصابون في جافا

أستخدم Eclipse Mars Release (4.5.0) لهذا البرنامج التعليمي ولكن أعتقد أن هذه الخطوات ستعمل مع الإصدارات القديمة من Eclipse أيضًا. تأكد أيضًا من أنك قد أضفت Apache Tomcat أو أي حاوية خدمة آخرى في Eclipse. دعنا نبدأ مع تنفيذ خدمة ويب Eclipse الآن.

مثال على خدمة ويب بالصابون

لنبدأ مع مثال خدمة الويب SOAP في برنامج Eclipse. أولاً وقبل كل شيء سنقوم بإنشاء مشروع ويب ديناميكي بسيط في برنامج Eclipse سيحتوي على منطق الأعمال الخاص بتطبيقنا. انقر فوق الزر التالي أعلاه وستحصل على صفحة التالية لتقديم اسم مشروع الويب الخاص بك وTarget Runtime. لاحظ أنني أستخدم Apache Tomcat 8 ، يمكنك أيضًا استخدام أي حاوية خدمة سيرفلت قياسية أخرى. انقر فوق التالي وسيُطلب منك تقديم “Context Root” وموقع دليل المحتوى. يمكنك تركهم كما هم افتراضيًا. انقر على الانتهاء وسيقوم برنامج Eclipse بإنشاء هيكل المشروع لك. لنبدأ مع منطق أعمالنا. لذا، لمثالنا، نود نشر خدمة ويب يمكن استخدامها لإضافة / حذف / الحصول على كائن. لذا، الخطوة الأولى هي إنشاء نموذج الشجرة.

package com.journaldev.jaxws.beans;

import java.io.Serializable;

public class Person implements Serializable{

	private static final long serialVersionUID = -5577579081118070434L;
	
	private String name;
	private int age;
	private int id;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}
	
	@Override
	public String toString(){
		return id+"::"+name+"::"+age;
	}

}

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

package com.journaldev.jaxws.service;

import com.journaldev.jaxws.beans.Person;

public interface PersonService {

	public boolean addPerson(Person p);
	
	public boolean deletePerson(int id);
	
	public Person getPerson(int id);
	
	public Person[] getAllPersons();
}

أدناه هو تنفيذ فئة الخدمة، نحن نستخدم Map لتخزين كائنات Person كمصدر بيانات. في البرمجة في العالم الحقيقي، نود حفظ هذه في جداول قاعدة البيانات.

package com.journaldev.jaxws.service;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import com.journaldev.jaxws.beans.Person;

public class PersonServiceImpl implements PersonService {

	private static Map<Integer,Person> persons = new HashMap<Integer,Person>();
	
	@Override
	public boolean addPerson(Person p) {
		if(persons.get(p.getId()) != null) return false;
		persons.put(p.getId(), p);
		return true;
	}

	@Override
	public boolean deletePerson(int id) {
		if(persons.get(id) == null) return false;
		persons.remove(id);
		return true;
	}

	@Override
	public Person getPerson(int id) {
		return persons.get(id);
	}

	@Override
	public Person[] getAllPersons() {
		Set<Integer> ids = persons.keySet();
		Person[] p = new Person[ids.size()];
		int i=0;
		for(Integer id : ids){
			p[i] = persons.get(id);
			i++;
		}
		return p;
	}

}

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

خدمات الويب SOAP في جافا باستخدام Eclipse

بمجرد أن يكون منطق الأعمال جاهزًا ، فإن الخطوة التالية هي استخدام بيئة البرمجة إكليبس لإنشاء تطبيق خدمة ويب من خلاله. أنشئ مشروعًا جديدًا وحدد معالج خدمة الويب. انقر على الزر التالي وستحصل على صفحة يجب توفير تفاصيل خدمة الويب وعميلها فيها. هذه هي الصفحة الأكثر أهمية في إنشاء خدمة الويب. تأكد من تحديد “نوع خدمة الويب” كـ “خدمة الويب الأساسية من نوع جاوة بين” لأننا نقوم بتنفيذها بناءً من الأسفل. هناك طريقتان لإنشاء خدمة الويب:

  1. طريقة التعاقد الأخيرة أو النهج من الأسفل: في هذا النهج ، نقوم أولاً بإنشاء التنفيذ ثم نقوم بإنشاء ملف WSDL منه. تناسب تنفيذتنا في هذه الفئة.
  2. طريقة التعاقد الأولى أو النهج من الأعلى: في هذا النهج ، نقوم أولاً بإنشاء عقد خدمة الويب أي ملف WSDL ثم نقوم بإنشاء التنفيذ لذلك.

في تنفيذ الخدمة، قدم فئة التنفيذ PersonServiceImpl بالمسار الكامل المصنف تصنيفًا تصنيفيًا. تأكد من تحريك المنزلق في نوع الخدمة ونوع العميل إلى الجانب الأيسر حتى يمكنه إنشاء برنامج العميل وأيضًا واجهة المستخدم لاختبار خدمة الويب الخاصة بنا. تحقق من التكوينات في تنفيذ خدمة الويب، يجب عليك تقديم التفاصيل الصحيحة لوقت التشغيل الخادم، ووقت تشغيل خدمة الويب ومشروع الخدمة. عادةً ما يتم ملؤها تلقائيًا ولا تحتاج إلى إجراء أي تغييرات هنا. بالنسبة لتكوينات العميل، يمكنك تقديم اسم مشروع العميل كما تريد. لقد تركته على الإعداد الافتراضي كـ SOAPExampleClient. إذا قمت بالنقر فوق الرابط لوقت تشغيل خدمة الويب، ستحصل على خيارات مختلفة كما هو موضح في الصورة أدناه. ومع ذلك، لقد تركتها كما هو موضح في الإعداد الافتراضي. انقر على الزر التالي ثم ستتمكن من اختيار الأساليب التي ترغب في تعريضها كخدمة ويب. ستتمكن أيضًا من اختيار نمط خدمة الويب سواءًا كان وثيقًا أو حرفيًا. يمكنك تغيير اسم مستند WSDL ولكن من الجيد أن يكون مع اسم فئة التنفيذ لتجنب الارتباك لاحقًا. انقر على الزر التالي وستحصل على صفحة بدء تشغيل الخادم، انقر على زر “بدء الخادم” ثم سيتم تمكين الزر التالي. انقر على الزر التالي وستحصل على صفحة لتشغيل “مستكشف خدمات الويب”. انقر فوق الزر للتشغيل وسيتم فتح نافذة جديدة في المتصفح حيث يمكنك اختبار خدمة الويب الخاصة بك قبل المضي قدمًا مع جزء تطبيق العميل. يبدو مثل الصورة أدناه لمشروعنا. يمكننا القيام ببعض الاختبارات هنا، ولكن بالنسبة لتطبيقنا البسيط أنا مستعد للمضي قدمًا بإنشاء تطبيق عميل. انقر على الزر التالي في نافذة تطبيقات الويب Eclipse وستحصل على صفحة لمجلد المصدر لتطبيق العميل. انقر على الزر التالي وستحصل على خيارات مختلفة للاختيار كمرفق اختبار. أنا ذاهب إلى الأمام مع JAX-RPC JSPs بحيث سيقوم تطبيق العميل بإنشاء صفحة JSP يمكننا استخدامها. لاحظ الأساليب getEndpoint() و setEndpoint(String) التي تمت إضافتها التي يمكننا استخدامها للحصول على عنوان URL لنقطة نهاية خدمة الويب ويمكننا تعيينها إلى بعض عنوان URL الآخر في حال نقل الخادم الخاص بنا إلى نقطة نهاية URL أخرى. انقر على زر Finish وسيقوم Eclipse بإنشاء مشروع العميل في مساحة العمل الخاصة بك، كما سيقوم بتشغيل صفحة JSP اختبار العميل كما هو موضح أدناه. يمكنك نسخ عنوان URL وفتحه في أي متصفح ترغب في ذلك. دعنا نختبر بعض الخدمات التي قمنا بتعريضها ونرى الناتج.

اختبار خدمة ويب SOAP في Eclipse

  • addPerson

  • getPerson

  • getAllPersons لاحظ أن تفاصيل الشخص لا تُطبع في قسم النتائج، وذلك لأنها تم إنشاؤها تلقائياً، ونحن بحاجة إلى إعادة تنظيمها قليلاً للحصول على الإخراج المطلوب. افتح Result.jsp في مشروع العميل وسترى أنه يستخدم switch case لإنشاء إخراج النتيجة. بالنسبة لطريقة getAllPersons()، كانت الحالة 42 في حالتي. لاحظ أنه يمكن أن تكون مختلفة تمامًا في حالتك. لقد قمت فقط بتغيير الكود للحالة 42 كما هو موضح أدناه.

    case 42:
            gotMethod = true;
            com.journaldev.jaxws.beans.Person[] getAllPersons42mtemp = samplePersonServiceImplProxyid.getAllPersons();
    if(getAllPersons42mtemp == null){
    %>
    <%=getAllPersons42mtemp %>
    <%
    }else{
            String tempreturnp43 = null;
            if(getAllPersons42mtemp != null){
            java.util.List<com.journaldev.jaxws.beans.Person> listreturnp43= java.util.Arrays.asList(getAllPersons42mtemp);
            //tempreturnp43 = listreturnp43.toString();
            for(com.journaldev.jaxws.beans.Person p : listreturnp43){
            	int id = p.getId();
            	int age = p.getAge();
            	String name=p.getName();
            	%>
            	<%=id%>::<%=name %>::<%=age %>
            	<%
            	}
            }
            }      
    break;
    

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

يبدو أن خدمة الويب وتطبيقات العميل تعمل بشكل جيد، تأكد من قضاء بعض الوقت في النظر إلى القوالب الجانبية للعميل التي تم إنشاؤها بواسطة Eclipse لفهم المزيد.

ملف WSDL وتكوينات خدمة الويب SOAP

وأخيرًا، ستلاحظ أن ملف WSDL تم إنشاؤه في مشروع خدمة الويب على النحو التالي. كود PersonServiceImpl.wsdl:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="https://service.jaxws.journaldev.com" xmlns:apachesoap="https://xml.apache.org/xml-soap" xmlns:impl="https://service.jaxws.journaldev.com" xmlns:intf="https://service.jaxws.journaldev.com" xmlns:tns1="https://beans.jaxws.journaldev.com" xmlns:wsdl="https://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="https://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="https://www.w3.org/2001/XMLSchema">
<!--WSDL created by Apache Axis version: 1.4
Built on Apr 22, 2006 (06:55:48 PDT)-->
 <wsdl:types>
  <schema elementFormDefault="qualified" targetNamespace="https://service.jaxws.journaldev.com" xmlns="https://www.w3.org/2001/XMLSchema">
   <import namespace="https://beans.jaxws.journaldev.com"/>
   <element name="addPerson">
    <complexType>
     <sequence>
      <element name="p" type="tns1:Person"/>
     </sequence>
    </complexType>
   </element>
   <element name="addPersonResponse">
    <complexType>
     <sequence>
      <element name="addPersonReturn" type="xsd:boolean"/>
     </sequence>
    </complexType>
   </element>
   <element name="deletePerson">
    <complexType>
     <sequence>
      <element name="id" type="xsd:int"/>
     </sequence>
    </complexType>
   </element>
   <element name="deletePersonResponse">
    <complexType>
     <sequence>
      <element name="deletePersonReturn" type="xsd:boolean"/>
     </sequence>
    </complexType>
   </element>
   <element name="getPerson">
    <complexType>
     <sequence>
      <element name="id" type="xsd:int"/>
     </sequence>
    </complexType>
   </element>
   <element name="getPersonResponse">
    <complexType>
     <sequence>
      <element name="getPersonReturn" type="tns1:Person"/>
     </sequence>
    </complexType>
   </element>
   <element name="getAllPersons">
    <complexType/>
   </element>
   <element name="getAllPersonsResponse">
    <complexType>
     <sequence>
      <element maxOccurs="unbounded" name="getAllPersonsReturn" type="tns1:Person"/>
     </sequence>
    </complexType>
   </element>
  </schema>
  <schema elementFormDefault="qualified" targetNamespace="https://beans.jaxws.journaldev.com" xmlns="https://www.w3.org/2001/XMLSchema">
   <complexType name="Person">
    <sequence>
     <element name="age" type="xsd:int"/>
     <element name="id" type="xsd:int"/>
     <element name="name" nillable="true" type="xsd:string"/>
    </sequence>
   </complexType>
  </schema>
 </wsdl:types>

   <wsdl:message name="addPersonResponse">

      <wsdl:part element="impl:addPersonResponse" name="parameters">

      </wsdl:part>

   </wsdl:message>

   <wsdl:message name="getAllPersonsResponse">

      <wsdl:part element="impl:getAllPersonsResponse" name="parameters">

      </wsdl:part>

   </wsdl:message>

   <wsdl:message name="deletePersonResponse">

      <wsdl:part element="impl:deletePersonResponse" name="parameters">

      </wsdl:part>

   </wsdl:message>

   <wsdl:message name="addPersonRequest">

      <wsdl:part element="impl:addPerson" name="parameters">

      </wsdl:part>

   </wsdl:message>

   <wsdl:message name="getPersonResponse">

      <wsdl:part element="impl:getPersonResponse" name="parameters">

      </wsdl:part>

   </wsdl:message>

   <wsdl:message name="getPersonRequest">

      <wsdl:part element="impl:getPerson" name="parameters">

      </wsdl:part>

   </wsdl:message>

   <wsdl:message name="deletePersonRequest">

      <wsdl:part element="impl:deletePerson" name="parameters">

      </wsdl:part>

   </wsdl:message>

   <wsdl:message name="getAllPersonsRequest">

      <wsdl:part element="impl:getAllPersons" name="parameters">

      </wsdl:part>

   </wsdl:message>

   <wsdl:portType name="PersonServiceImpl">

      <wsdl:operation name="addPerson">

         <wsdl:input message="impl:addPersonRequest" name="addPersonRequest">

       </wsdl:input>

         <wsdl:output message="impl:addPersonResponse" name="addPersonResponse">

       </wsdl:output>

      </wsdl:operation>

      <wsdl:operation name="deletePerson">

         <wsdl:input message="impl:deletePersonRequest" name="deletePersonRequest">

       </wsdl:input>

         <wsdl:output message="impl:deletePersonResponse" name="deletePersonResponse">

       </wsdl:output>

      </wsdl:operation>

      <wsdl:operation name="getPerson">

         <wsdl:input message="impl:getPersonRequest" name="getPersonRequest">

       </wsdl:input>

         <wsdl:output message="impl:getPersonResponse" name="getPersonResponse">

       </wsdl:output>

      </wsdl:operation>

      <wsdl:operation name="getAllPersons">

         <wsdl:input message="impl:getAllPersonsRequest" name="getAllPersonsRequest">

       </wsdl:input>

         <wsdl:output message="impl:getAllPersonsResponse" name="getAllPersonsResponse">

       </wsdl:output>

      </wsdl:operation>

   </wsdl:portType>

   <wsdl:binding name="PersonServiceImplSoapBinding" type="impl:PersonServiceImpl">

      <wsdlsoap:binding style="document" transport="https://schemas.xmlsoap.org/soap/http"/>

      <wsdl:operation name="addPerson">

         <wsdlsoap:operation soapAction=""/>

         <wsdl:input name="addPersonRequest">

            <wsdlsoap:body use="literal"/>

         </wsdl:input>

         <wsdl:output name="addPersonResponse">

            <wsdlsoap:body use="literal"/>

         </wsdl:output>

      </wsdl:operation>

      <wsdl:operation name="deletePerson">

         <wsdlsoap:operation soapAction=""/>

         <wsdl:input name="deletePersonRequest">

            <wsdlsoap:body use="literal"/>

         </wsdl:input>

         <wsdl:output name="deletePersonResponse">

            <wsdlsoap:body use="literal"/>

         </wsdl:output>

      </wsdl:operation>

      <wsdl:operation name="getPerson">

         <wsdlsoap:operation soapAction=""/>

         <wsdl:input name="getPersonRequest">

            <wsdlsoap:body use="literal"/>

         </wsdl:input>

         <wsdl:output name="getPersonResponse">

            <wsdlsoap:body use="literal"/>

         </wsdl:output>

      </wsdl:operation>

      <wsdl:operation name="getAllPersons">

         <wsdlsoap:operation soapAction=""/>

         <wsdl:input name="getAllPersonsRequest">

            <wsdlsoap:body use="literal"/>

         </wsdl:input>

         <wsdl:output name="getAllPersonsResponse">

            <wsdlsoap:body use="literal"/>

         </wsdl:output>

      </wsdl:operation>

   </wsdl:binding>

   <wsdl:service name="PersonServiceImplService">

      <wsdl:port binding="impl:PersonServiceImplSoapBinding" name="PersonServiceImpl">

         <wsdlsoap:address location="https://localhost:8080/SOAPExample/services/PersonServiceImpl"/>

      </wsdl:port>

   </wsdl:service>

</wsdl:definitions>

إذا فتحته في وضع التصميم في Eclipse، سيبدو كما في الصورة أدناه. يمكنك أيضًا الوصول إلى ملف WSDL لخدمة الويب عن طريق المتصفح عن طريق إلحاق ?wsdl بنقطة نهاية خدمة الويب. ستلاحظ أيضًا أن web.xml تم تعديله لاستخدام Apache Axis كجهاز تحكم أمامي لخدمة الويب.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xmlns="https://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="https://xmlns.jcp.org/xml/ns/javaee https://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>SOAPExample</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <display-name>Apache-Axis Servlet</display-name>
    <servlet-name>AxisServlet</servlet-name>
    <servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>AxisServlet</servlet-name>
    <url-pattern>/servlet/AxisServlet</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>AxisServlet</servlet-name>
    <url-pattern>*.jws</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>AxisServlet</servlet-name>
    <url-pattern>/services/*</url-pattern>
  </servlet-mapping>
  <servlet>
    <display-name>Axis Admin Servlet</display-name>
    <servlet-name>AdminServlet</servlet-name>
    <servlet-class>org.apache.axis.transport.http.AdminServlet</servlet-class>
    <load-on-startup>100</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>AdminServlet</servlet-name>
    <url-pattern>/servlet/AdminServlet</url-pattern>
  </servlet-mapping>
</web-app>

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

Source:
https://www.digitalocean.com/community/tutorials/soap-webservices-in-java-example-eclipse