מבוא ל- Apache CXF

1. סקירה כללית

Apache CXF היא מסגרת תואמת לחלוטין של JAX-WS.

בנוסף לתכונות המוגדרות על ידי תקני JAX-WS, אפאצ'י CXF מספק יכולת המרה בין מחלקות WSDL ו- Java, ממשקי API המשמשים לניהול הודעות XML גולמיות, תמיכה ב- JAX-RS, שילוב עם Spring Framework וכו '.

מדריך זה הוא הראשון בסדרה על Apache CXF, המציג מאפיינים בסיסיים של המסגרת. היא משתמשת רק בממשקי ה- API הסטנדרטיים של JAX-WS בקוד המקור ועדיין מנצלת את Apache CXF מאחורי הקלעים, כגון מטא נתונים מסוג WSDL שנוצרו אוטומטית ותצורת ברירת מחדל של CXF.

2. תלות Maven

התלות העיקרית הדרושה לשימוש ב- Apache CXF היא org.apache.cxf: cxf - rt - חזית -jaxws. זה מספק יישום JAX-WS להחלפת ה- JDK המובנה:

 org.apache.cxf cxf-rt-frontend-jaxws 3.1.6 

שימו לב שחפץ זה מכיל קובץ בשם javax.xml.ws.spi.Provider בתוך ה META-INF / שירותים מַדרִיך. Java VM מסתכל על השורה הראשונה בקובץ זה כדי לקבוע את יישום ה- JAX-WS לשימוש בו. במקרה זה, תוכן השורה הוא org.apache.cxf.jaxws.spi.ProviderImpl, בהתייחס ליישום המסופק על ידי Apache CXF.

במדריך זה איננו משתמשים במיכל סרוולט כדי לפרסם את השירות, ולכן נדרשת תלות נוספת בכדי לספק הגדרות דרושות מסוג Java:

 org.apache.cxf cxf-rt-transports-http-jetty 3.1.6 

לקבלת הגרסאות העדכניות ביותר של תלות אלה, אנא עיין ב cxf-rt-frontend-jaxws ו cxf-rt-transports-http-jetty במאגר המרכזי של Maven.

3. נקודת סיום של שירות האינטרנט

נתחיל ממעמד היישום המשמש להגדרת תצורת נקודת הקצה של השירות:

@WebService (endpointInterface = "com.baeldung.cxf.introduction.Baeldung") בכיתה ציבורית BaeldungImpl מיישמת Baeldung {תלמידים מפה פרטית = חדש LinkedHashMap (); ציבורי שלום מחרוזת (שם מחרוזת) {להחזיר "שלום" + שם; } מחרוזת ציבורית helloStudent (סטודנט סטודנט) {students.put (students.size () + 1, סטודנט); להחזיר "שלום" + student.getName (); } getStudents מפה ציבורית () {תלמידים חוזרים; }}

הדבר החשוב ביותר שיש לשים לב לכאן הוא נוכחותו של ה endpointInterface תכונה ב @שירות רשת ביאור. מאפיין זה מצביע על ממשק המגדיר חוזה מופשט לשירות האינטרנט.

יש ליישם את כל חתימות השיטות המוצהרות בממשק נקודות הקצה, אך אין צורך ליישם את הממשק.

הנה ה BaeldungImpl מחלקת יישום עדיין מיישמת את ממשק נקודות הקצה הבא כדי להבהיר כי כל השיטות המוצהרות של הממשק יושמו, אך פעולה זו היא אופציונלית:

ממשק ציבורי @WebService Baeldung {מחרוזת ציבורית שלום (שם מחרוזת); מחרוזת ציבורית helloStudent (סטודנט סטודנט); @XmlJavaTypeAdapter (StudentMapAdapter.class) מפה ציבורית getStudents (); }

כברירת מחדל, Apache CXF משתמש ב- JAXB כארכיטקטורת קשירת הנתונים שלה. עם זאת, מכיוון ש- JAXB אינה תומכת ישירות בכריכה של א מַפָּה, אשר מוחזר מה- getStudents שיטה, אנחנו צריכים מתאם כדי להמיר את מַפָּה לשיעור Java בו JAXB יכול להשתמש.

בנוסף, על מנת להפריד בין אלמנטים חוזיים ליישומם, אנו מגדירים סטוּדֶנט כממשק וגם JAXB אינו תומך ישירות בממשקים, ולכן אנו זקוקים למתאם אחד נוסף כדי להתמודד עם זה. למעשה, מטעמי נוחות, אנו עשויים להכריז סטוּדֶנט כמחלקה. השימוש בסוג זה כממשק הוא רק הדגמה נוספת לשימוש בשיעורי הסתגלות.

המתאמים מודגמים בסעיף ממש למטה.

4. מתאמים מותאמים אישית

סעיף זה ממחיש את הדרך להשתמש בשיעורי הסתגלות לתמיכה בכריכה של ממשק Java ו- מַפָּה באמצעות JAXB.

4.1. מתאם ממשק

כך ה סטוּדֶנט ממשק מוגדר:

@XmlJavaTypeAdapter (StudentAdapter.class) ממשק ציבורי תלמיד {public String getName (); }

ממשק זה מצהיר רק על שיטה אחת המחזירה א חוּט ומפרט סטודנט מתאם כמעמד ההסתגלות למיפוי עצמו לסוג שממנו ניתן להחיל מחייב JAXB וממנו.

ה סטודנט מתאם הכיתה מוגדרת כדלקמן:

מחלקה ציבורית StudentAdapter מרחיב את XmlAdapter {ציבורי StudentImpl ציבורי (סטודנט סטודנט) זורק חריג {אם (סטודנט למשל של StudentImpl) {תלמיד (חזרה (StudentImpl); } להחזיר StudentImpl חדש (student.getName ()); } סטודנט ציבורי unmarshal (StudentImpl סטודנט) זורק חריג {תלמיד חוזר; }}

שיעור הסתגלות חייב ליישם את מתאם Xml ממשק ולספק יישום עבור מַרשַׁל ו לא מרשל שיטות. ה מַרשַׁל שיטה הופכת סוג מאוגד (סטוּדֶנט, ממשק ש- JAXB לא יכול לטפל בו ישירות לסוג ערך (StudentImpl, מעמד בטון שניתן לעבד על ידי JAXB). ה לא מרשל השיטה עושה את הדברים להיפך.

הנה ה StudentImpl הגדרת כיתה:

@XmlType (name = "Student") מחלקה ציבורית StudentImpl מיישם תלמיד {פרטי שם מחרוזת; // בונים, גטר וקובע}

4.2. מַפָּה מַתאֵם

ה getStudents שיטה של באלדונג ממשק נקודות קצה מחזיר א מַפָּה ומציין כיתת הסתגלות להמרה מַפָּה לסוג שניתן לטפל בו על ידי JAXB. דומה ל סטודנט מתאם בכיתה, מחלקת הסתגלות זו חייבת ליישם מַרשַׁל ו לא מרשל שיטות של מתאם Xml מִמְשָׁק:

מחלקה ציבורית StudentMapAdapter מרחיב את XmlAdapter {ציבורי StudentMap ציבורי (MapMapMap) זורק Exception {StudentMap valueMap = StudentMap חדש (); עבור (Map.Entry boundEntry: boundMap.entrySet ()) {StudentMap.StudentEntry valueEntry = new StudentMap.StudentEntry (); valueEntry.setStudent (boundEntry.getValue ()); valueEntry.setId (boundEntry.getKey ()); valueMap.getEntries (). add (valueEntry); } להחזיר valueMap; } Unmarshal של מפה ציבורית (StudentMap valueMap) זורק חריג {Map boundMap = new LinkedHashMap (); עבור (StudentMap.StudentEntry studentEntry: valueMap.getEntries ()) {boundMap.put (studentEntry.getId (), studentEntry.getStudent ()); } להחזיר את boundMap; }}

ה StudentMapAdapter מפות כיתתיות מַפָּה אל וממנו StudentMap סוג ערך עם ההגדרה כדלקמן:

@XmlType (name = "StudentMap") מחלקה ציבורית StudentMap {ערכי רשימה פרטית = ArrayList חדש (); @XmlElement (nillable = false, name = "entry") רשימה ציבורית getEntries () {ערכי החזרה; } @ XmlType (name = "StudentEntry") מחלקה סטטית ציבורית StudentEntry {מזהה שלם פרטי; סטודנט סטודנט פרטי; // גטרים וקובעים}}

5. פריסה

5.1. שרת הַגדָרָה

על מנת לפרוס את שירות האינטרנט שנדון לעיל, נשתמש בממשקי ה- API הרגילים של JAX-WS. מכיוון שאנחנו משתמשים ב- Apache CXF, המסגרת עושה עבודה נוספת, למשל. יצירת ופרסום סכימת WSDL. כך מוגדר שרת השירות:

מחלקה ציבורית שרת {ציבורי ריק ריק סטטי (מחרוזת טוענת []) זורק InterruptedException {BaeldungImpl מיישם = BaeldungImpl חדש (); כתובת מחרוזת = "// localhost: 8080 / baeldung"; Endpoint.publish (כתובת, מיישם); Thread.sleep (60 * 1000); System.exit (0); }}

לאחר שהשרת פעיל זמן מה בכדי להקל על הבדיקה, יש לכבות אותו בכדי לשחרר משאבי מערכת. אתה יכול לציין כל משך עבודה עבור השרת על פי צרכיך על ידי העברת ארוך ויכוח ל חוט. שינה שיטה.

5.2. פריסת ה- שרת

במדריך זה אנו משתמשים ב- org.codehaus.mojo: exec -maven-plugin תוסף לאינסטינציה של השרת שתואר לעיל ולשלוט במחזור החיים שלו. זה הוכרז בקובץ Maven POM כדלקמן:

 org.codehaus.mojo exec-maven-plugin com.baeldung.cxf.introduction.Server 

ה mainClass תצורה מתייחסת ל שרת מחלקה שבה מתפרסמת נקודת הסיום של שירות האינטרנט. לאחר הפעלת ה- ג'אווה המטרה של תוסף זה, נוכל לבדוק את סכימת ה- WSDL שנוצרה אוטומטית על ידי Apache CXF על ידי גישה לכתובת האתר // localhost: 8080 / baeldung? wsdl.

6. מקרי מבחן

חלק זה מנחה אתכם בשלבים לכתיבת מקרי בדיקה ששימשו לאימות שירות האינטרנט שיצרנו קודם.

שים לב שעלינו לבצע את exec: java המטרה להפעיל את שרת שירות האינטרנט לפני הפעלת בדיקה כלשהי.

6.1. הכנה

הצעד הראשון הוא להכריז על מספר שדות עבור כיתת הבדיקה:

מחלקה ציבורית StudentTest {QName SERVICE_NAME פרטי סטטי = QName חדש ("// Introduction.cxf.baeldung.com/", "Baeldung"); QName סטטי פרטי PORT_NAME = QName חדש ("// הקדמה.קקספ.באלדונג. com", "BaeldungPort"); שירות שירות פרטי; פרטי Baeldung baeldungProxy; פרטי BaeldungImpl baeldungImpl; // הצהרות אחרות}

בלוק האתחול הבא משמש ליזום ה- שֵׁרוּת שדה של javax.xml.ws.Service הקלד לפני הפעלת כל בדיקה:

{service = Service.create (SERVICE_NAME); מחרוזת endpointAddress = "// localhost: 8080 / baeldung"; service.addPort (PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING, endpointAddress); }

לאחר הוספת תלות JUnit לקובץ POM, נוכל להשתמש ב- @לפני הערה כמו בקטע הקוד שלמטה. שיטה זו פועלת לפני כל בדיקה כדי להפעיל מחדש באלדונג שדות:

@ לפני הריק הציבורי מחזיר מחדש את BaeldungInstances () {baeldungImpl = BaeldungImpl new (); baeldungProxy = service.getPort (PORT_NAME, Baeldung.class); }

ה baeldungProxy משתנה הוא שרת proxy עבור נקודת הקצה של שירות האינטרנט, בעוד baeldungImpl הוא פשוט אובייקט Java פשוט. אובייקט זה משמש להשוואת תוצאות הפעלות על שיטות נקודת קצה מרוחקות דרך ה- proxy לבין הפעלות על שיטות מקומיות.

שים לב כי א QName מופע מזוהה על ידי שני חלקים: URI של Namespace וחלק מקומי. אם ה PORT_NAME טענה, של QName סוג, של Service.getPort השיטה הושמטה, Apache CXF יניח כי URI של Namespace של הארגומנט הוא שם החבילה של ממשק נקודות הקצה בסדר הפוך והחלק המקומי שלו הוא שם הממשק שצורף נמל, שהוא אותו ערך בדיוק של PORT_NAME. לכן, במדריך זה אנו עשויים להשאיר טיעון זה בחוץ.

6.2. יישום מבחן

מקרה הבדיקה הראשון שאנו מדגימים בפרק משנה זה הוא לאמת את התגובה שהוחזרה מהפעלה מרחוק של ה- שלום שיטה בנקודת הקצה של השירות:

@ מבחן ציבורי בטל כאשר משתמשיםHelloMethod_thenCorrect () {מחרוזת endpointResponse = baeldungProxy.hello ("Baeldung"); מחרוזת localResponse = baeldungImpl.hello ("Baeldung"); assertEquals (localResponse, endpointResponse); }

ברור ששיטת נקודת הקצה המרוחקת מחזירה את אותה תגובה כמו השיטה המקומית, כלומר שירות האינטרנט פועל כצפוי.

מקרה הבדיקה הבא מדגים את השימוש ב- שלום סטודנט שיטה:

@ מבחן פומבי בטל כאשר משתמשיםHelloStudentMethod_thenCorrect () {סטודנט סטודנט = StudentImpl חדש ("ג'ון דו"); מחרוזת endpointResponse = baeldungProxy.helloStudent (סטודנט); מחרוזת localResponse = baeldungImpl.helloStudent (סטודנט); assertEquals (localResponse, endpointResponse); }

במקרה זה הלקוח מגיש א סטוּדֶנט מתנגד לנקודת הסיום ומקבל בתמורה הודעה המכילה את שם התלמיד. כמו מקרה המבחן הקודם, גם התגובות של הפניות מרחוק וגם מקומי זהות.

מקרה המבחן האחרון שאנו מציגים כאן מורכב יותר. כפי שהוגדר על ידי מחלקת הטמעת נקודות הקצה של השירות, בכל פעם שהלקוח מזמין את ה- שלום סטודנט השיטה על נקודת הקצה, הוגשה סטוּדֶנט האובייקט יאוחסן במטמון. ניתן להשיג מטמון זה על ידי התקשרות ל getStudents שיטה בנקודת הקצה. מקרה הבדיקה הבא מאשר את התוכן של סטודנטים מטמון מייצג את מה שהלקוח שלח לשירות האינטרנט:

@ מבחן ציבורי בטל באמצעות GetStudentsMethod_thenCorrect () {סטודנט סטודנט 1 = סטודנט חדש ("אדם"); baeldungProxy.helloStudent (student1); סטודנט סטודנט 2 = StudentImpl חדש ("חוה"); baeldungProxy.helloStudent (student2); מפה תלמידים = baeldungProxy.getStudents (); assertEquals ("אדם", students.get (1) .getName ()); assertEquals ("Eve", students.get (2) .getName ()); }

7. מסקנה

הדרכה זו הציגה את Apache CXF, מסגרת חזקה לעבודה עם שירותי אינטרנט בג'אווה. היא התמקדה ביישום המסגרת כמימוש JAX-WS סטנדרטי, תוך שימוש ביכולות הספציפיות של המסגרת בזמן הריצה.

ניתן למצוא את היישום של כל הדוגמאות וקטעי הקוד בפרויקט GitHub.


$config[zx-auto] not found$config[zx-overlay] not found