כותרת הנושא היא באמת שאלה, כי... אני עצמי לא יודע מה זה ולראשונה אנסה לעבוד עם זה במסגרת המאמר הזה. הדבר היחיד שאני יכול להבטיח הוא שהקוד המוצג להלן יעבוד, אבל הביטויים שלי יהיו רק הנחות וניחושים לגבי איך אני עצמי מבין את כל זה. אז בוא נלך...
מבוא
אנחנו צריכים להתחיל עם הסיבה שהקונספט של שירותי אינטרנט נוצר. בזמן שהמושג הזה הופיע בעולם, כבר היו קיימות טכנולוגיות שאפשרו ליישומים לקיים אינטראקציה מרחוק, שבה תוכנה אחת יכולה לקרוא לשיטה כלשהי בתוכנה אחרת, שאפשר להפעיל אותה במחשב שנמצא בעיר אחרת או אפילו במדינה אחרת. כל זה נקרא בקיצור RPC (Remote Procedure Calling). דוגמאות כוללות טכנולוגיות CORBA, ועבור Java - RMI (Remote Method Invoking). ונראה שהכל טוב בהם, במיוחד ב-CORBA, כי... אתה יכול לעבוד עם זה בכל שפת תכנות, אבל משהו עדיין היה חסר. אני מאמין שהחיסרון של CORBA הוא שהיא פועלת באמצעות כמה מפרוטוקולי רשת משלה במקום HTTP פשוט, שיתאים לכל חומת אש. הרעיון של שירות האינטרנט היה ליצור RPC שיוכנס לתוך מנות HTTP. כך החל פיתוח התקן. מהם המושגים הבסיסיים של תקן זה:- סבון . לפני קריאה להליך מרחוק, עליך לתאר שיחה זו בקובץ XML בפורמט SOAP. SOAP הוא פשוט אחד מסימוני XML רבים המשמשים בשירותי אינטרנט. כל מה שאנחנו רוצים לשלוח לאנשהו דרך HTTP מומר תחילה לתיאור XML SOAP, ואז נדחס לחבילת HTTP ונשלח למחשב אחר ברשת באמצעות TCP/IP.
- WSDL . יש שירות אינטרנט, כלומר. תוכנית שניתן לקרוא לשיטות שלה מרחוק. אבל התקן מחייב שהתוכנית הזו תהיה מלווה בתיאור שאומר ש"כן, אתה צודק - זה באמת שירות אינטרנט ואפשר לקרוא ממנו לשיטות כאלה ואחרות". תיאור זה מיוצג על ידי קובץ XML אחר, בעל פורמט שונה, כלומר WSDL. הָהֵן. WSDL הוא רק קובץ XML המתאר שירות אינטרנט ותו לא.
גישה כללית
בשירותי אינטרנט תמיד יש לקוח ושרת. השרת הוא שירות האינטרנט שלנו ולפעמים נקרא נקודת הקצה (כמו בנקודת הסיום שאליה מגיעים הודעות SOAP מהלקוח). אנחנו צריכים לעשות את הפעולות הבאות:- תאר את הממשק של שירות האינטרנט שלנו
- הטמע את הממשק הזה
- הפעל את שירות האינטרנט שלנו
- כתוב לקוח והתקשר מרחוק לשיטת שירות האינטרנט הרצויה
main
ולהפעיל את שירות האינטרנט ישירות כשרת, או לפרוס אותו לשרת כמו Tomcat או כל אחר. במקרה השני, אנחנו בעצמנו לא מפעילים שרת חדש ולא פותחים פורט נוסף במחשב, אלא פשוט אומרים לקונטיינר של Tomcat servlet ש"כתבנו כאן שיעורי שרות אינטרנט, אנא פרסמו אותם כדי שכל מי שיוצר איתך קשר יוכל השתמש בשירות האינטרנט שלנו." ללא קשר לשיטת השקת שירות האינטרנט, יהיה לנו אותו לקוח.
שרת
בואו נשיק את IDEA וניצור פרויקט חדש צור פרויקט חדש . ציין את השם HelloWebService ולחץ על הלחצן הבא ולאחר מכן על הלחצן סיום . בתיקיית src ניצור את החבילה ru.javarush.ws . בחבילה זו ניצור ממשקHelloWebService
:
package ru.javarush.ws;
// это аннотации, т.е. способ отметить наши классы и методы,
// How связанные с веб-сервисной технологией
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
// говорим, что наш интерфейс будет работать How веб-сервис
@WebService
// говорим, что веб-сервис будет использоваться для вызова методов
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface HelloWebService {
// говорим, что этот метод можно вызывать удаленно
@WebMethod
public String getHelloString(String name);
}
בקוד זה, המחלקות הן מה שנקרא הערות WebService
ואינן WebMethod
עושות דבר מלבד לסמן את הממשק שלנו ואת השיטה שלו כשירות אינטרנט. כך גם לגבי הכיתה SOAPBinding
. ההבדל היחיד הוא שזה SOAPBinding
ביאור עם פרמטרים. במקרה זה, נעשה שימוש בפרמטר style
עם ערך המציין ששירות האינטרנט יעבוד לא באמצעות הודעות מסמך, אלא כ-RPC קלאסי, כלומר. לקרוא לשיטה. בואו ליישם את היגיון הממשק שלנו וניצור מחלקה בחבילה שלנו HelloWebServiceImpl
. אגב, אני מציין שסיום מחלקה עם Impl הוא קונבנציה בג'אווה, לפיה יישום ממשקים מיועד כך (Impl - מהמילה implementation, כלומר יישום). זו לא דרישה ואתה חופשי לקרוא לכיתה איך שאתה רוצה, אבל נימוסים טובים דורשים זאת:
package ru.javarush.ws;
// таже annotation, что и при описании интерфейса,
import javax.jws.WebService;
// но здесь используется с параметром endpointInterface,
// указывающим полное Name класса интерфейса нашего веб-сервиса
@WebService(endpointInterface = "ru.javarush.ws.HelloWebService")
public class HelloWebServiceImpl implements HelloWebService {
@Override
public String getHelloString(String name) {
// просто возвращаем приветствие
return "Hello, " + name + "!";
}
}
בואו נשיק את שירות האינטרנט שלנו כשרת עצמאי, כלומר. ללא השתתפות של כל Tomcat ושרתי יישומים (זהו נושא לדיון נפרד). לשם כך, במבנה הפרויקט שבתיקיית src , ניצור חבילה ru.javarush.endpoint
ובה ניצור מחלקה HelloWebServicePublisher
עם מתודה main
:
package ru.javarush.endpoint;
// класс, для запуска веб-serverа с веб-сервисами
import javax.xml.ws.Endpoint;
// класс нашего веб-сервиса
import ru.javarush.ws.HelloWebServiceImpl;
public class HelloWebServicePublisher {
public static void main(String... args) {
// запускаем веб-server на порту 1986
// и по addressу, указанному в первом аргументе,
// запускаем веб-сервис, передаваемый во втором аргументе
Endpoint.publish("http://localhost:1986/wss/hello", new HelloWebServiceImpl());
}
}
עכשיו בואו נריץ מחלקה זו על ידי לחיצה על Shift+F10 . שום דבר לא יופיע במסוף, אבל השרת פועל. אתה יכול לאמת זאת על ידי הקלדת השורה http://localhost:1986/wss/hello?wsdl בדפדפן שלך . העמוד שנפתח, מצד אחד, מוכיח שיש לנו שרת אינטרנט (http://) הפועל על יציאה 1986 במחשב שלנו (localhost), ומצד שני, מציג תיאור WSDL של שירות האינטרנט שלנו. אם תפסיק את היישום, התיאור יהפוך לבלתי זמין, וכך גם שירות האינטרנט עצמו, כך שלא נעשה זאת, אלא נעבור לכתיבת הלקוח.
לָקוּחַ
בתיקיית הפרויקט src ניצור חבילהru.javarush.client
, ובתוכה מחלקה HelloWebServiceClient
עם מתודה main
:
package ru.javarush.client;
// нужно, чтобы получить wsdl описание и через него
// дотянуться до самого веб-сервиса
import java.net.URL;
// такой эксепшн возникнет при работе с an objectом URL
import java.net.MalformedURLException;
// классы, чтобы пропарсить xml-ку c wsdl описанием
// и дотянуться до тега service в нем
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
// интерфейс нашего веб-сервиса (нам больше и нужно)
import ru.javarush.ws.HelloWebService;
public class HelloWebServiceClient {
public static void main(String[] args) throws MalformedURLException {
// создаем ссылку на wsdl описание
URL url = new URL("http://localhost:1986/wss/hello?wsdl");
// Параметры следующего конструктора смотрим в самом первом теге WSDL описания - definitions
// 1-ый аргумент смотрим в атрибуте targetNamespace
// 2-ой аргумент смотрим в атрибуте name
QName qname = new QName("http://ws.javarush.ru/", "HelloWebServiceImplService");
// Теперь мы можем дотянуться до тега service в wsdl описании,
Service service = Service.create(url, qname);
// а далее и до вложенного в него тега port, чтобы
// получить ссылку на удаленный от нас an object веб-сервиса
HelloWebService hello = service.getPort(HelloWebService.class);
// Ура! Теперь можно вызывать удаленный метод
System.out.println(hello.getHelloString("JavaRush"));
}
}
נתתי מקסימום הערות על הקוד ברישום. אין לי מה להוסיף, אז בוא נרוץ (Shift+F10). אנחנו צריכים לראות את הטקסט במסוף: Hello, JavaRush!
אם לא ראית אותו, כנראה שכחת להפעיל את שירות האינטרנט.
GO TO FULL VERSION