Apache CXF - คู่มือฉบับย่อ
ในสภาพแวดล้อมปัจจุบันคุณสามารถสร้างแอปพลิเคชันบริการบนเว็บโดยใช้ตัวเลือกต่างๆ คุณสามารถใช้โปรโตคอลมาตรฐานและเป็นที่ยอมรับอย่างกว้างขวางอย่างน้อยหนึ่งรายการสำหรับการสื่อสาร ตัวอย่างเช่นSOAP , XML / HTTP, RESTful HTTPและCORBA (Common Object Request Broker Architecture ซึ่งเป็นที่นิยมอย่างมากในสมัยก่อน แต่ไม่ได้ใช้บ่อยนักในปัจจุบัน
นอกจากนี้คุณยังมีทางเลือกของการขนส่งที่แตกต่างกันเช่น HTTP ที่JMS , JBIและทางเลือกของ front-end ของ API เหมือนJAX-RSและJAX-WS การมีตัวเลือกมากมายสำหรับการพัฒนาบริการเว็บจึงจำเป็นต้องมีเฟรมเวิร์กบริการโอเพนซอร์สเพื่อรวมตัวเลือกที่กล่าวถึงข้างต้นทั้งหมดเข้าด้วยกันและนั่นคือสิ่งที่Apache CXFทำ
ในบทช่วยสอนนี้คุณจะได้เรียนรู้วิธีใช้ CXF เพื่อสร้างทั้งบริการเว็บและไคลเอนต์ที่ใช้บริการโดยใช้ตัวเลือกอย่างน้อยหนึ่งตัวที่เราได้ระบุไว้ข้างต้น บทช่วยสอนนี้จะแนะนำคุณตลอดการพัฒนาโค้ดสำหรับทั้งเซิร์ฟเวอร์และไคลเอนต์ เนื่องจากแต่ละแอปพลิเคชันสามารถใช้ตัวเลือกเดียวจากแต่ละหมวดหมู่ ได้แก่ ส่วนหน้าการขนส่งและโปรโตคอลเมื่อพิจารณาถึงการเรียงลำดับและการรวมกันของทั้งสามนี้จำนวนแอปพลิเคชันจะสูงมากเกินไป
บทช่วยสอนนี้กล่าวถึงการพัฒนาโครงการต่อไปนี้โดยละเอียด -
CXF พร้อมออบเจ็กต์ Apache CXF เก่าธรรมดา (POJO)
CXF กับ JAX-WS
CXF พร้อม WSDL
CXF พร้อม JAX-RS
CXF กับ JMS
เพื่อให้ง่ายเราได้ใช้ maven กับอินเทอร์เฟซบรรทัดคำสั่ง คุณสามารถใช้ IDE ที่คุณต้องการเพื่อสร้างโครงการ maven
ในบทถัดไปให้เราเริ่มต้นด้วยบทแรก
ในบทนี้คุณจะได้เรียนรู้วิธีการพัฒนาเว็บแอปพลิเคชันง่ายๆที่ส่งข้อความทักทายไปยังผู้ใช้ โครงการบริการเว็บใช้แบบจำลองWSDL CXF ช่วยให้คุณสามารถซ่อนโมเดล WSDL นี้ได้โดยจัดเตรียมฟรอนต์เอนด์อย่างง่ายเพื่อแมป Apache CXF API กับ WSDL ที่อยู่เบื้องหลัง
ในโครงการที่ง่ายที่สุดนี้อินเทอร์เฟซของบริการเว็บจะเปิดเผยโดยตรงกับไคลเอนต์และไคลเอนต์จะใช้ Apache CXF API ดั้งเดิมเพื่อเรียกใช้บริการเว็บ
ขั้นแรกเราจะสร้างบริการเว็บ ทุกบริการมีอินเทอร์เฟซที่เปิดเผยกับไคลเอนต์ เราอาจเขียนอินเทอร์เฟซนี้เป็นอินเตอร์เฟส Apache CXF แบบธรรมดาหรือเป็นเอกสาร WSDL ในแนวทาง Apache CXF-First นี้เราจะเปิดเผยบริการของเราผ่านอินเทอร์เฟซ Apache CXF
การพัฒนาบริการเว็บ
บริการที่เรากำลังจะสร้างบนเว็บจะมีวิธีการเว็บเดียวที่เรียกว่า greetings. วิธีนี้ใช้เวลา astringพิมพ์อาร์กิวเมนต์ซึ่งเราจะส่งชื่อผู้ใช้ บริการจะส่งข้อความทักทายกลับไปยังผู้โทรพร้อมชื่อผู้ใช้ที่ได้รับรวมอยู่ในข้อความ
อินเทอร์เฟซบริการเว็บ
เพื่อแสดงอินเทอร์เฟซของบริการบนเว็บของเราเราจะสร้างอินเทอร์เฟซ Apache CXF ดังต่อไปนี้ -
//HelloWorld.java
package com.tutorialspoint.cxf.pojo;
public interface HelloWorld {
String greetings(String text);
}
อินเทอร์เฟซมีเพียงวิธีเดียวที่เรียกว่า greetings. เซิร์ฟเวอร์จะใช้อินเทอร์เฟซนี้ ในแอปพลิเคชันที่ไม่สำคัญของเราอินเทอร์เฟซนี้จะเปิดเผยกับลูกค้าโดยตรง โดยทั่วไปในแอปพลิเคชันบริการบนเว็บคุณใช้ WSDL เพื่ออธิบายอินเทอร์เฟซบริการบนเว็บ ในแอปพลิเคชั่นง่ายๆนี้เราจะมอบอินเทอร์เฟซโดยตรงนี้ให้กับนักพัฒนาลูกค้า จากนั้นลูกค้าจะโทรไปที่ไฟล์greetingsข้อความบนวัตถุเซิร์ฟเวอร์ ก่อนอื่นให้เราสร้างบริการเว็บ
การติดตั้งบริการเว็บ
HelloWorld อินเทอร์เฟซถูกนำมาใช้ในไฟล์ HelloWorldImpl คลาส Apache CXF ดังแสดงด้านล่าง -
//HelloWorldImpl.java
package com.tutorialspoint.cxf.pojo;
public class HelloWorldImpl implements HelloWorld {
@Override
public String greetings(String text) {
return "Hi " + text;
}
}
greetings วิธีการรับพารามิเตอร์ของ string พิมพ์ต่อท้ายข้อความทักทายและส่งคืนสตริงผลลัพธ์ไปยังผู้โทร
ต่อไปเราเขียนแอปพลิเคชันเซิร์ฟเวอร์เพื่อโฮสต์ไฟล์ HelloWorld บริการ.
การสร้างเซิร์ฟเวอร์
แอปพลิเคชันเซิร์ฟเวอร์ประกอบด้วยสองส่วน -
ส่วนแรกสร้างโรงงานสำหรับบริการเว็บของเราและ
ส่วนที่สองเขียนไฟล์ main วิธีการสร้างอินสแตนซ์
เซิร์ฟเวอร์ใช้ ServerFactoryBean คลาสที่จัดทำโดยไลบรารี CXF เพื่อแสดงไฟล์ HelloWorldส่วนต่อประสานกับไคลเอนต์ระยะไกล ดังนั้นก่อนอื่นเราจึงสร้างตัวอย่างไฟล์ServerFactoryBean คลาสแล้วตั้งค่าคุณสมบัติต่างๆ -
ServerFactoryBean factory = new ServerFactoryBean();
เราตั้งค่าคลาสบริการที่จะเรียกโดยการโทร setServiceClass วิธีการบน factory วัตถุ -
factory.setServiceClass(HelloWorld.class);
เราตั้งค่า URL สำหรับเรียกใช้บริการของเราโดยโทรไปที่โรงงาน setAddressวิธี. โปรดทราบว่าบริการจะเผยแพร่ที่ URL นี้
factory.setAddress("http://localhost:5000/Hello");
ในกรณีนี้บริการจะถูกปรับใช้บนเซิร์ฟเวอร์แบบฝังและจะรับฟังพอร์ต 5000 คุณสามารถเลือกหมายเลขพอร์ตใดก็ได้ที่คุณต้องการ
ก่อนที่จะสร้างโรงงานคุณต้องแจ้งให้โรงงานทราบเกี่ยวกับคลาสการใช้บริการของเรา ซึ่งทำได้โดยเรียกไฟล์setServiceBean วิธีการบน factory วัตถุดังแสดงที่นี่ -
factory.setServiceBean(new HelloWorldImpl());
ถั่วบริการถูกตั้งค่าเป็นอินสแตนซ์ของคลาสการใช้งานบริการของเรา ในที่สุดเราก็สร้างโรงงานโดยเรียกมันว่าcreate วิธีการ -
factory.create();
ในขณะที่เราได้พัฒนาโรงงานเพื่อให้บริการเว็บของเราเราจะเขียนไฟล์ main วิธีการสร้างอินสแตนซ์และทำให้มันทำงานต่อไป
ตอนนี้เขียน main วิธีการสร้างอินสแตนซ์ไฟล์ HelloServer ชั้นเรียนดังนี้ -
public static void main(String[] args) throws Exception {
new HelloServer();
System.out.println("Listening on port 5000 ...");
}
เมื่อสร้างอินสแตนซ์แล้วไฟล์ HelloServerชั้นเรียนจะทำงานไปเรื่อย ๆ สำหรับการใช้งานจริงคุณจะทำให้เซิร์ฟเวอร์ของคุณทำงานตลอดไปอย่างแน่นอน ในสถานการณ์ปัจจุบันเราจะยุติเซิร์ฟเวอร์หลังจากเวลาที่กำหนดไว้ดังนี้ -
Thread.sleep(5 * 60 * 1000);
System.out.println("Server exiting ...");
System.exit(0);
รหัสทั้งหมดสำหรับ HelloServer ชั้นเรียนได้รับด้านล่าง -
//HelloServer.java
//HelloServer.java
package com.tutorialspoint.cxf.pojo;
import org.apache.cxf.frontend.ServerFactoryBean;
public class HelloServer {
protected HelloServer() throws Exception {
ServerFactoryBean factory = new ServerFactoryBean();
factory.setServiceClass(HelloWorld.class);
factory.setAddress("http://localhost:5000/Hello");
factory.setServiceBean(new HelloWorldImpl());
factory.create();
}
public static void main(String[] args) throws Exception {
new HelloServer();
System.out.println("Listening on port 5000 ...");
Thread.sleep(5 * 60 * 1000);
System.out.println("Server exiting ...");
System.exit(0);
}
}
แอปพลิเคชันเซิร์ฟเวอร์ที่เราสร้างขึ้นใช้ ServerFactoryBeanคลาสจากไลบรารี CXF ตอนนี้เราต้องรวมไลบรารีเหล่านี้ไว้ในโครงการของเราเพื่อรวบรวมไฟล์HelloServerชั้นเรียน. เราจะใช้Maven เพื่อตั้งค่าการอ้างอิงโครงการ
การตั้งค่าโครงการ Maven
ในการสร้างโครงการ Maven ให้พิมพ์คำสั่งต่อไปนี้ในหน้าต่างบรรทัดคำสั่งของคุณ โปรดทราบว่าเราได้ทดสอบสิ่งนี้บนเครื่อง Mac สำหรับการติดตั้ง Windows และ Linux คำแนะนำอาจแตกต่างกันในบางที่
mvn archetype:generate
เมื่อถูกถามถึงคุณสมบัติให้ป้อนค่าต่อไปนี้ -
Define value for property 'groupId': : com.tutorialspoint
Define value for property 'artifactId': : cxf-pojo
Define value for property 'version': 1.0-SNAPSHOT: : 1.0
Define value for property 'package': com.tutorialspoint: : com.tutorialspoint.cxf.pojo
เมื่อคำสั่ง maven เสร็จสมบูรณ์คุณจะพบโครงสร้างโฟลเดอร์ที่เหมาะสมที่สร้างขึ้นในโฟลเดอร์ปัจจุบันของคุณพร้อมกับไฟล์ pom.xml
โครงสร้างไดเร็กทอรีที่สร้างขึ้นจะแสดงที่นี่ -
คุณจะเพิ่มการอ้างอิง CXF ในไฟล์ pom.xmlและคัดลอกไฟล์ Apache CXF ที่สร้างไว้ด้านบนไปยังโฟลเดอร์ที่เหมาะสมของโครงสร้างที่สร้างมาเวน สำหรับข้อมูลอ้างอิงที่พร้อมใช้งานของคุณเราได้ระบุไว้ด้านล่างไฟล์ pom.xml สำหรับโปรเจ็กต์ที่เราสร้างบนเครื่องของเรา
<?xml version = "1.0" encoding = "UTF-8"?>
<project xmlns = "http://maven.apache.org/POM/4.0.0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.tutorialspoint</groupId>
<artifactId>cxf-pojo</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<profiles>
<profile>
<id>server</id>
<build>
<defaultGoal>test</defaultGoal>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>
com.tutorialspoint.cxf.pojo.HelloServer
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>client</id>
<build>
<defaultGoal>test</defaultGoal>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>
com.tutorialspoint.cxf.pojo.HelloClient
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-features-logging</artifactId>
<version>3.3.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-simple</artifactId>
<version>3.3.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.3.0</version>
</dependency>
<!-- Jetty is needed if you're using the CXFServlet -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.3.0</version>
</dependency>
</dependencies>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
</project>
pom.xml ข้างต้นอาจมีการอ้างอิงเพิ่มเติมซึ่งไม่เกี่ยวข้องกับโปรเจ็กต์นี้ แต่จำเป็นสำหรับโปรเจ็กต์ถัดไปของเราในบทช่วยสอนนี้ อย่างไรก็ตามไม่มีอันตรายใด ๆ ในการรวมการอ้างอิงเพิ่มเติม
โครงสร้างโฟลเดอร์โครงการ
โครงสร้างโฟลเดอร์โครงการบนเครื่องของฉันหลังจากวางเซิร์ฟเวอร์และไฟล์ Apache CXF ของไคลเอนต์แสดงไว้ด้านล่างสำหรับการอ้างอิงอย่างรวดเร็วของคุณ -
กำลังรันเซิร์ฟเวอร์
ในการสร้างโครงการให้ใช้คำสั่งต่อไปนี้ในหน้าต่างบรรทัดคำสั่งของคุณ -
mvn clean install
คุณสามารถเริ่มเซิร์ฟเวอร์โดยใช้คำสั่งต่อไปนี้ -
mvn -Pserver
สิ่งนี้จะเริ่มต้นเซิร์ฟเวอร์และคุณจะเห็นข้อความแจ้งต่อไปนี้บนคอนโซล -
INFO: Creating Service {http://pojo.cxf.tutorialspoint.com/}HelloWorld from class com.tutorialspoint.cxf.pojo.HelloWorld
INFO: Setting the server's publish address to be http://localhost:5000/Hello
Listening on port 5000 ...
ตอนนี้ในหน้าต่างเบราว์เซอร์ของคุณระบุ URL ของบริการที่เผยแพร่ของเรา คุณจะเห็นผลลัพธ์ต่อไปนี้ -
นี่เป็นการยืนยันว่าบริการของเรากำลังทำงานที่พอร์ตที่ระบุบน localhost เนื่องจากเราไม่ได้ระบุไฟล์greetings ข้อความในการโทรของเราข้อความแจ้งข้อผิดพลาด SOAP จะถูกส่งกลับไปยังเบราว์เซอร์
คุณสามารถทดสอบบริการเว็บของคุณเพิ่มเติมโดยใช้ไคลเอนต์ SOAP ที่คุณเลือก ที่นี่เราได้ใช้Postmanเพื่อทดสอบเซิร์ฟเวอร์ของเรา
ผลลัพธ์เป็นดังที่แสดงไว้ที่นี่ -
สังเกตว่า SOAP Requestถูกเข้ารหัสด้วยมือ หลังจากโพสต์คำขอเซิร์ฟเวอร์ส่งไฟล์SOAP Response ข้อความซึ่งจะเห็นในส่วนล่างของภาพหน้าจอ
จากสิ่งนี้คุณสามารถเข้าใจได้ว่า CXF รักษาการใช้โปรโตคอล SOAP สำหรับทั้งคำขอและการตอบกลับในขณะที่ให้มุมมองแบบรวมสำหรับเทคโนโลยีเว็บที่หลากหลายที่มีอยู่ในโลกปัจจุบัน สิ่งนี้ทำให้การพัฒนาเว็บแอปพลิเคชันง่ายขึ้นอย่างมาก
งานต่อไปของเราคือการสร้างไคลเอนต์ที่จะใช้บริการเว็บที่คุณสร้างขึ้น
การสร้างลูกค้า
ในแอปพลิเคชันเซิร์ฟเวอร์ HelloWorldเป็นอินเทอร์เฟซที่แสดงบริการเว็บของเรา บริการเว็บเองก็แค่ส่งข้อความทักทายธรรมดาให้กับลูกค้า โดยปกติแล้วอินเทอร์เฟซบริการเว็บจะเปิดเผยต่อโลกภายนอกโดยใช้ WSDL (Web Services Description Language) ในแอปพลิเคชันที่ไม่สำคัญนี้เราจะเปิดเผยบริการเว็บของเราให้กับลูกค้าโดยการเปิดเผยอินเทอร์เฟซบริการโดยตรงและนั่นคือHelloWorld.class.
เพื่อจุดประสงค์นี้ CXF จึงจัดเตรียมคลาสโรงงานที่เรียกว่า ClientProxyFactoryBean ที่ช่วยให้เราสามารถเชื่อมต่อกับอินเทอร์เฟซที่ต้องการกับอินสแตนซ์โรงงานที่สร้างขึ้น
ขั้นแรกเราสร้างอินสแตนซ์ของโรงงานถั่วดังนี้ -
ClientProxyFactoryBean factory = new ClientProxyFactoryBean();
เราเรียกว่า setAddressวิธีการบนอินสแตนซ์บีนโรงงานเพื่อตั้งค่า URL ที่สามารถเรียกใช้บริการเว็บของเราได้ ในกรณีของเราเราจะใช้ URL ที่ใช้ในการสร้างเซิร์ฟเวอร์ในขั้นตอนก่อนหน้านี้ -
factory.setAddress("http://localhost:5000/Hello");
ต่อไปเราเรียกว่า create วิธีการบน factory อินสแตนซ์เพื่อแนบอินเทอร์เฟซบริการของเรา HelloWorld.class ไปเลย
HelloWorld helloServer = factory.create(HelloWorld.class);
สุดท้ายเราเรียก greetings วิธีการเรียกใช้บริการเว็บระยะไกล
System.out.println(helloServer.greetings(System.getProperty("user.name")));
สิ่งนี้จะพิมพ์ข้อความทักทายบนคอนโซลของคุณ
แหล่งที่มาทั้งหมดสำหรับแอปพลิเคชันไคลเอนต์แสดงอยู่ด้านล่าง -
//HelloClient.java
package com.tutorialspoint.cxf.pojo;
import org.apache.cxf.frontend.ClientProxyFactoryBean;
public class HelloClient {
public static void main(String[] args) throws Exception {
ClientProxyFactoryBean factory = new ClientProxyFactoryBean();
factory.setAddress("http://localhost:5000/Hello");
HelloWorld helloServer = factory.create(HelloWorld.class);
System.out.println(helloServer.greetings(System.getProperty("user.name")));
}
}
กำลังเรียกใช้ไคลเอ็นต์
ตรวจสอบให้แน่ใจว่าเซิร์ฟเวอร์ยังคงทำงานอยู่บนเครื่องของคุณ ในกรณีที่หมดเวลาให้รีสตาร์ทเซิร์ฟเวอร์ด้วยคำสั่งต่อไปนี้ -
mvn -Pserver
คุณจะเห็นข้อความต่อไปนี้บนคอนโซล -
Listening on port 5000 ...
ตอนนี้ก่อนที่เซิร์ฟเวอร์จะหมดเวลาซึ่งเราตั้งไว้เป็น 5 นาทีให้เปิดหน้าต่างบรรทัดคำสั่งอื่นและเริ่มไคลเอนต์ด้วยคำสั่งต่อไปนี้ -
mvn -Pclient
คุณจะเห็นข้อความที่คล้ายกับข้อความต่อไปนี้ในบรรทัดคำสั่ง -
Hi tutorialspoint
โปรดทราบว่า tutorialspointคือชื่อผู้ใช้ของเรา คุณจะได้รับคำทักทายด้วยชื่อของคุณเอง
ในบทถัดไปเราจะเรียนรู้วิธีใช้ CXF ในโครงการ JAX-WS (Apache CXF API สำหรับ XML Web Services)
ในแอปพลิเคชัน JAX-WS นี้เราจะใช้วิธีการแรกของ Apache CXF เหมือนกับแอปพลิเคชัน POJO รุ่นก่อนหน้า ก่อนอื่นเราจะสร้างอินเทอร์เฟซสำหรับบริการเว็บของเรา
การประกาศอินเทอร์เฟซบริการ
เช่นเดียวกับในกรณีก่อนหน้านี้เราจะสร้างบริการเล็กน้อยที่มีวิธีการติดต่อเพียงวิธีเดียวที่เรียกว่าการทักทาย รหัสสำหรับอินเทอร์เฟซบริการแสดงอยู่ด้านล่าง -
//HelloWorld.java
package com.tutorialspoint.cxf.jaxws.helloworld;
import javax.jws.WebService;
@WebService
public interface HelloWorld {
String greetings(String text);
}
เราใส่คำอธิบายประกอบอินเทอร์เฟซด้วยไฟล์ @WebServiceแท็ก ต่อไปเราจะใช้อินเทอร์เฟซนี้
การใช้งานเว็บอินเตอร์เฟส
การใช้งานเว็บอินเตอร์เฟสแสดงไว้ที่นี่ -
//HelloWorldImpl.java
package com.tutorialspoint.cxf.jaxws.helloworld;
public class HelloWorldImpl implements HelloWorld {
@Override
public String greetings(String name) {
return ("hi " + name);
}
}
วิธีการทักทายมีคำอธิบายประกอบ @Overrideแท็ก วิธีนี้จะส่งคืนข้อความ "hi" ไปยังผู้โทร
ต่อไปเราจะเขียนโค้ดสำหรับพัฒนาเซิร์ฟเวอร์
กำลังพัฒนาเซิร์ฟเวอร์
ซึ่งแตกต่างจากแอปพลิเคชัน POJO ตอนนี้เราจะแยกส่วนต่อประสานโดยใช้คลาส Endpoint ที่จัดเตรียมไว้ให้ CXF เพื่อเผยแพร่บริการของเรา สิ่งนี้ทำได้ในโค้ดสองบรรทัดต่อไปนี้ -
HelloWorld implementor = new HelloWorldImpl();
Endpoint.publish(
"http://localhost:9090/HelloServerPort",
implementor,
new LoggingFeature()
);
พารามิเตอร์แรกของวิธีการเผยแพร่ระบุ URL ที่จะให้บริการของเราแก่ลูกค้า พารามิเตอร์ที่สองระบุคลาสการใช้งานสำหรับบริการของเรา รหัสทั้งหมดสำหรับเซิร์ฟเวอร์แสดงอยู่ด้านล่าง -
//Server.java
package com.tutorialspoint.cxf.jaxws.helloworld;
import javax.xml.ws.Endpoint;
import org.apache.cxf.ext.logging.LoggingFeature;
public class Server {
public static void main(String[] args) throws Exception {
HelloWorld implementor = new HelloWorldImpl();
Endpoint.publish("http://localhost:9090/HelloServerPort",
implementor,
new LoggingFeature());
System.out.println("Server ready...");
Thread.sleep(5 * 60 * 1000);
System.out.println("Server exiting ...");
System.exit(0);
}
}
ในการปรับใช้เซิร์ฟเวอร์ของเราคุณจะต้องทำการแก้ไขเพิ่มเติมเล็กน้อยในโครงการของคุณตามรายการด้านล่าง
การปรับใช้เซิร์ฟเวอร์
สุดท้ายในการปรับใช้แอ็พพลิเคชันเซิร์ฟเวอร์คุณจะต้องทำการปรับเปลี่ยนอีกครั้งใน pom.xml เพื่อตั้งค่าแอปพลิเคชันของคุณเป็นเว็บแอปพลิเคชัน รหัสที่คุณต้องเพิ่มลงในไฟล์pom.xml ได้รับด้านล่าง -
<profiles>
<profile>
<id>server</id>
<build>
<defaultGoal>test</defaultGoal>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>
com.tutorialspoint.cxf.jaxws.helloworld.Server
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
ก่อนที่คุณจะปรับใช้แอปพลิเคชันคุณต้องเพิ่มไฟล์อีกสองไฟล์ในโปรเจ็กต์ของคุณ สิ่งเหล่านี้แสดงในภาพหน้าจอด้านล่าง -
ไฟล์เหล่านี้เป็นไฟล์มาตรฐาน CXF ซึ่งกำหนดการแม็ปสำหรับ CXFServlet. รหัสภายในweb.xml ไฟล์จะแสดงที่นี่สำหรับการอ้างอิงอย่างรวดเร็วของคุณ -
//Web.xml
<?xml version = "1.0" encoding = "UTF-8"??>
<web-app xmlns = "http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5"
xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>cxf</display-name>
<servlet>
<description>Apache CXF Endpoint</description>
<display-name>cxf</display-name>
<servlet-name>cxf</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>
1
</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>
cxf
</servlet-name>
<url-pattern>
/services/*
</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>60</session-timeout>
</session-config>
</web-app>
ใน cxf-servlet.xml,คุณประกาศคุณสมบัติสำหรับปลายทางของบริการของคุณ สิ่งนี้แสดงในข้อมูลโค้ดด้านล่าง -
<beans ...>
<jaxws:endpoint xmlns:helloworld = "http://tutorialspoint.com/"
id = "helloHTTP"
address = "http://localhost:9090/HelloServerPort"
serviceName = "helloworld:HelloServiceService"
endpointName = "helloworld:HelloServicePort">
</jaxws:endpoint>
</beans>
ที่นี่เรากำหนดรหัสสำหรับปลายทางบริการของเราที่อยู่ที่จะให้บริการชื่อบริการและชื่อปลายทาง ตอนนี้คุณได้เรียนรู้ว่าบริการของคุณได้รับการกำหนดเส้นทางและประมวลผลโดย servlet CXF อย่างไร
pom.xml สุดท้าย
pom.xmlรวมการอ้างอิงเพิ่มเติมอีกเล็กน้อย แทนที่จะอธิบายการอ้างอิงทั้งหมดเราได้รวมเวอร์ชันสุดท้ายของ pom.xml ไว้ด้านล่าง -
<?xml version = "1.0" encoding = "UTF-8"??>
<project xmlns = "http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.tutorialspoint</groupId>
<artifactId>cxf-jaxws</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<profiles>
<profile>
<id>server</id>
<build>
<defaultGoal>test</defaultGoal>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>
com.tutorialspoint.cxf.jaxws.helloworld.Server
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>client</id>
<build>
<defaultGoal>test</defaultGoal>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>java</goal>
<goals>
<configuration>
<mainClass>
com.tutorialspoint.cxf.jaxws.helloworld.Client
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-features-logging</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.3.0</version>
</dependency>
</dependencies>
</project>
โปรดทราบว่ายังมีโปรไฟล์สำหรับการสร้างไคลเอนต์ที่เราจะเรียนรู้ในส่วนต่อไปของบทช่วยสอนนี้
เรียกใช้บริการ HelloWorld
ตอนนี้คุณพร้อมที่จะเรียกใช้เว็บแอปแล้ว ในหน้าต่างคำสั่งให้รันสคริปต์บิลด์โดยใช้คำสั่งต่อไปนี้
mvn clean install
mvn -Pserver
คุณจะเห็นข้อความต่อไปนี้บนคอนโซล -
INFO: Setting the server's publish address to be http://localhost:9090/HelloServerPort
Server ready…
เช่นเดียวกับก่อนหน้านี้คุณสามารถทดสอบเซิร์ฟเวอร์ได้โดยเปิด URL ของเซิร์ฟเวอร์ในเบราว์เซอร์ของคุณ
เนื่องจากเราไม่ได้ระบุการดำเนินการใด ๆ มีเพียงข้อความแสดงข้อผิดพลาดเท่านั้นที่ถูกส่งกลับไปยังเบราว์เซอร์โดยแอปพลิเคชันของเรา
ตอนนี้ลองเพิ่มไฟล์ ?wsdl ไปยัง URL ของคุณและคุณจะเห็นผลลัพธ์ต่อไปนี้ -
แอปพลิเคชันเซิร์ฟเวอร์ของเราจึงทำงานตามที่คาดไว้ คุณสามารถใช้ SOAP Client เช่นPostman อธิบายไว้ก่อนหน้านี้เพื่อทดสอบบริการของคุณเพิ่มเติม
ในส่วนถัดไปเราจะเรียนรู้วิธีการเขียนลูกค้าที่ใช้บริการของเรา
การพัฒนาลูกค้า
การเขียนไคลเอ็นต์ในแอปพลิเคชัน CXF นั้นไม่สำคัญพอ ๆ กับการเขียนเซิร์ฟเวอร์ นี่คือรหัสที่สมบูรณ์สำหรับลูกค้า -
//Client.java
package com.tutorialspoint.cxf.jaxws.helloworld;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.soap.SOAPBinding;
public final class Client {
private static final QName SERVICE_NAME
= new QName("http://helloworld.jaxws.cxf.tutorialspoint.com/",
"HelloWorld");
private static final QName PORT_NAME
= new QName("http://helloworld.jaxws.cxf.tutorialspoint.com/",
"HelloWorldPort");
private Client() {
}
public static void main(String[] args) throws Exception {
Service service = Service.create(SERVICE_NAME);
System.out.println("service created");
String endpointAddress = "http://localhost:9090/HelloServerPort";
service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING,
endpointAddress);
HelloWorld hw = service.getPort(HelloWorld.class);
System.out.println(hw.greetings("World"));
}
}
ที่นี่เราใช้ CXF ที่ให้มา Serviceคลาสเพื่อผูกกับบริการที่รู้จัก เราเรียกว่าcreate วิธีการบน Serviceคลาสเพื่อรับอินสแตนซ์ของบริการ เราตั้งค่าพอร์ตที่รู้จักโดยเรียกไฟล์addPort วิธีการบน service ตัวอย่าง.
ตอนนี้เราพร้อมที่จะใช้บริการซึ่งเราทำได้โดยการรับอินเทอร์เฟซบริการก่อนโดยโทรไปที่ไฟล์ getPort วิธีการบน serviceตัวอย่าง. สุดท้ายเราเรียกgreetings วิธีการพิมพ์ข้อความทักทายบนคอนโซล
ตอนนี้เมื่อคุณได้เรียนรู้พื้นฐานของ CXF โดยใช้แนวทาง Apache CXF-First ตอนนี้คุณจะได้เรียนรู้วิธีใช้ CXF กับแนวทาง WSDL-First ในบทถัดไปของเรา
แอปพลิเคชัน CXF-POJO ที่คุณพัฒนาส่งผลให้เกิดการมีเพศสัมพันธ์ที่แน่นหนามากระหว่างไคลเอนต์และเซิร์ฟเวอร์ การให้เข้าถึงอินเทอร์เฟซบริการโดยตรงอาจก่อให้เกิดภัยคุกคามด้านความปลอดภัยที่รุนแรง ดังนั้นการแยกส่วนระหว่างไคลเอนต์และเซิร์ฟเวอร์จึงเป็นที่ต้องการซึ่งทำได้โดยใช้ WSDL (Web Services Description Language)
เราเขียนอินเทอร์เฟซบริการเว็บในเอกสาร WSDL ซึ่งใช้ XML เราจะใช้เครื่องมือเพื่อแมปอินเทอร์เฟซ WSDL นี้กับ Apache CXF ซึ่งจะนำไปใช้งานและใช้งานโดยไคลเอนต์และแอปพลิเคชันเซิร์ฟเวอร์ของเรา สำหรับการแยกชิ้นส่วนการเริ่มต้นด้วย WSDL เป็นวิธีที่ต้องการ สำหรับสิ่งนี้คุณต้องเรียนรู้ภาษาใหม่ก่อน - WSDL การเขียน WSDL จำเป็นต้องมีแนวทางที่รอบคอบและจะดีกว่าถ้าคุณสามารถทำความเข้าใจเกี่ยวกับเรื่องนี้ก่อนที่จะเริ่มดำเนินการ
ในบทเรียนนี้เราจะเริ่มต้นด้วยการกำหนดส่วนต่อประสานบริการเว็บในเอกสาร WSDL เราจะเรียนรู้วิธีใช้ CXF เพื่อสร้างทั้งเซิร์ฟเวอร์และแอปพลิเคชันไคลเอนต์โดยเริ่มจาก WSDL เราจะทำให้แอปพลิเคชั่นใช้งานง่ายเพื่อรักษาความสำคัญของการใช้ CXF หลังจากสร้างแอปพลิเคชันเซิร์ฟเวอร์แล้วเราจะเผยแพร่ไปยัง URL ที่ต้องการโดยใช้คลาส CXF ในตัว
ขั้นแรกให้เราอธิบาย WSDL ที่เราจะใช้
WSDL สำหรับ HelloWorld
บริการเว็บที่เรากำลังจะนำไปใช้จะมีวิธีการเดียวที่เรียกว่า webmethod greetings ที่ยอมรับไฟล์ stringพารามิเตอร์ถือชื่อผู้ใช้และส่งกลับข้อความสตริงไปยังผู้โทรหลังจากผนวกข้อความทักทายเข้ากับชื่อผู้ใช้ wsdl ที่สมบูรณ์แสดงไว้ด้านล่าง -
//Hello.wsdl
<?xml version = "1.0" encoding = "UTF-8"?>
<wsdl:definitions xmlns:soap = "http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns = "http://helloworld.tutorialspoint.com/"
xmlns:wsdl = "http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd = "http://www.w3.org/2001/XMLSchema"
name = "HelloWorld"
targetNamespace = "http://helloworld.tutorialspoint.com/">
<wsdl:types>
<xsd:schema attributeFormDefault = "unqualified"
elementFormDefault = "qualified"
targetNamespace = "http://helloworld.tutorialspoint.com/">
<xsd:element name = "greetings" type = "tns:greetings"/>
<xsd:complexType name = "greetings">
<xsd:sequence>
<xsd:element minOccurs = "0" name = "arg0" type = "xsd:string"/>
</xsd:sequence>
</xsd:complexType>
<xsd:element name = "greetingsResponse"
type = "tns:greetingsResponse"/>
<xsd:complexType name = "greetingsResponse">
<xsd:sequence>
<xsd:element minOccurs = "0" name = "return" type = "xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
</wsdl:types>
<wsdl:message name = "greetings">
<wsdl:part element = "tns:greetings" name = "parameters"> </wsdl:part>
</wsdl:message>
<wsdl:message name = "greetingsResponse">
<wsdl:part element = "tns:greetingsResponse" name = "parameters"> </wsdl:part>
</wsdl:message>
<wsdl:portType name = "HelloWorldPortType">
<wsdl:operation name = "greetings">
<wsdl:input message = "tns:greetings" name = "greetings"> </wsdl:input>
<wsdl:output message = "tns:greetingsResponse" name = "greetingsResponse">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name = "HelloWorldSoapBinding" type = "tns:HelloWorldPortType">
<soap:binding style = "document"
transport = "http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name = "greetings">
<soap:operation soapAction = "" style = "document"/>
<wsdl:input name = "greetings"></wsdl:input>
<wsdl:output name = "greetingsResponse">
<soap:body use = "literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name = "HelloWorldService">
<wsdl:port binding = "tns:HelloWorldSoapBinding" name = "HelloWorldPort">
<soap:address location = "http://localhost:9090/HelloServerPort"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
โปรดทราบว่าการเขียน wsdl ที่ถูกต้องตามหลักไวยากรณ์เป็นสิ่งที่ท้าทายสำหรับนักพัฒนาเสมอ มีเครื่องมือมากมายและตัวแก้ไขออนไลน์สำหรับสร้าง wsdl ผู้แก้ไขเหล่านี้จะขอชื่อของข้อความที่คุณต้องการใช้พร้อมกับพารามิเตอร์ที่คุณต้องการส่งผ่านในข้อความและประเภทของข้อความส่งคืนที่คุณต้องการให้แอปพลิเคชันไคลเอ็นต์ของคุณได้รับ หากคุณรู้จักไวยากรณ์ wsdl คุณสามารถเขียนโค้ดให้กับเอกสารทั้งหมดหรือใช้เครื่องมือแก้ไขเพื่อสร้างขึ้นเอง
ใน wsdl ข้างต้นเราได้กำหนดข้อความเดียวที่เรียกว่า greetings. ข้อความจะถูกส่งไปยังบริการที่เรียกว่าHelloWorldService ที่กำลังทำงานอยู่ที่ http://localhost:9090/HelloServerPort.
ด้วยเหตุนี้เราจะดำเนินการพัฒนาเซิร์ฟเวอร์ต่อไป ก่อนที่จะพัฒนาเซิร์ฟเวอร์เราจำเป็นต้องสร้างอินเทอร์เฟซ Apache CXF ในบริการเว็บของเรา สิ่งนี้จะต้องทำจาก wsdl ที่กำหนด ในการดำเนินการนี้ให้คุณใช้เครื่องมือที่เรียกว่าwsdl2java.
ปลั๊กอิน wsdl2java
เนื่องจากเราจะใช้ maven ในการสร้างโครงการคุณจะต้องเพิ่มปลั๊กอินต่อไปนี้ในไฟล์ pom.xml ไฟล์.
<plugins>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<wsdlOptions>
<wsdlOption>
<wsdl>src/main/resources/hello.wsdl</wsdl>
<faultSerialVersionUID> 1 </faultSerialVersionUID>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
โปรดทราบว่าเราระบุตำแหน่งของไฟล์ wsdl ไฟล์เป็น src/main/resources/Hello.wsdl. คุณจะต้องแน่ใจว่าคุณได้สร้างโครงสร้างไดเร็กทอรีที่เหมาะสมสำหรับโปรเจ็กต์ของคุณและเพิ่มสิ่งที่แสดงก่อนหน้านี้hello.wsdl ไฟล์ไปยังโฟลเดอร์ที่ระบุ
wsdl2javaปลั๊กอินจะรวบรวม wsdl นี้และสร้างคลาส Apache CXF ในโฟลเดอร์ที่กำหนดไว้ล่วงหน้า โครงสร้างโครงการทั้งหมดแสดงไว้ที่นี่สำหรับการอ้างอิงพร้อมของคุณ
ตอนนี้คุณพร้อมที่จะสร้างเซิร์ฟเวอร์โดยใช้ไฟล์ wsdl2javaสร้างคลาส คลาสที่ wsdl2java สร้างขึ้นจะแสดงในรูปด้านล่าง -
อินเทอร์เฟซบริการที่สร้างขึ้น
ในรายการคลาสที่สร้างขึ้นคุณต้องสังเกตว่าหนึ่งในนั้นคืออินเทอร์เฟซ Apache CXF - นี่คือ HelloWorldPortType.java. ตรวจสอบไฟล์นี้ในโปรแกรมแก้ไขโค้ดของคุณ เนื้อหาของไฟล์จะแสดงไว้ที่นี่สำหรับการอ้างอิงของคุณ -
//HelloWorldPortType.java
package com.tutorialspoint.helloworld;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;
/**
* This class was generated by Apache CXF 3.3.0
* 2019-02-11T12:05:55.220+05:30
* Generated source version: 3.3.0
*
*/
@WebService(targetNamespace = "http://helloworld.tutorialspoint.com/",
name = "HelloWorldPortType")
@XmlSeeAlso({ObjectFactory.class})
public interface HelloWorldPortType {
@WebMethod
@RequestWrapper(localName = "greetings", targetNamespace =
"http://helloworld.tutorialspoint.com/", className =
"com.tutorialspoint.helloworld.Greetings")
@ResponseWrapper(localName = "greetingsResponse", targetNamespace =
"http://helloworld.tutorialspoint.com/", className =
"com.tutorialspoint.helloworld.GreetingsResponse")
@WebResult(name = "return", targetNamespace =
"http://helloworld.tutorialspoint.com/")
public java.lang.String greetings(
@WebParam(name = "arg0", targetNamespace =
"http://helloworld.tutorialspoint.com/")
java.lang.String arg0
);
}
โปรดสังเกตว่าอินเทอร์เฟซมีวิธีการที่เรียกว่า greetings. นี่คือประเภทข้อความใน wsdl ของเรา wsdl2javaเครื่องมือได้เพิ่มวิธีนี้ในอินเทอร์เฟซที่สร้างขึ้น ตอนนี้คุณสามารถเข้าใจแล้วว่าข้อความใดก็ตามที่คุณเขียนใน wsdl วิธีการที่เกี่ยวข้องจะถูกสร้างขึ้นในอินเทอร์เฟซ
ตอนนี้งานของคุณคือใช้วิธีการเหล่านี้ทั้งหมดที่สอดคล้องกับข้อความต่างๆที่คุณกำหนดไว้ใน wsdl ของคุณ โปรดทราบว่าในตัวอย่างก่อนหน้านี้ของ Apache CXF-First เราเริ่มต้นด้วยอินเทอร์เฟซ Apache CXF สำหรับบริการเว็บของเรา ในกรณีนี้อินเทอร์เฟซ Apache CXF ถูกสร้างขึ้นจาก wsdl
การใช้อินเทอร์เฟซบริการ
การใช้อินเทอร์เฟซบริการเป็นเรื่องเล็กน้อย การใช้งานเต็มรูปแบบแสดงอยู่ในรายการด้านล่าง -
//HelloWorldImpl.java
package com.tutorialspoint.helloworld;
public class HelloWorldImpl implements HelloWorldPortType {
@Override
public String greetings(String name) {
return ("hi " + name);
}
}
รหัสใช้วิธีการเชื่อมต่อเดียวที่เรียกว่า greetings. วิธีนี้ใช้พารามิเตอร์หนึ่งตัวของstring พิมพ์ข้อความ "hi" ล่วงหน้าและส่งกลับสตริงผลลัพธ์ไปยังผู้โทร
ต่อไปเราจะเขียนแอปพลิเคชันเซิร์ฟเวอร์
กำลังพัฒนาเซิร์ฟเวอร์
การพัฒนาแอปพลิเคชันเซิร์ฟเวอร์เป็นเรื่องเล็กน้อยอีกครั้ง ที่นี่เราจะใช้ CXF ที่ให้มาEndpointชั้นเรียนเพื่อเผยแพร่บริการของเรา สิ่งนี้ทำได้ในโค้ดสองบรรทัดต่อไปนี้ -
HelloWorldPortType implementor = new HelloWorldImpl();
Endpoint.publish("http://localhost:9090/HelloServerPort",
implementor,
new LoggingFeature());
ขั้นแรกเราสร้างวัตถุของคลาสผู้ใช้บริการของเรา - HelloWorldImpl. จากนั้นเราส่งการอ้างอิงนี้เป็นพารามิเตอร์ที่สองไปยังไฟล์publishวิธี. พารามิเตอร์แรกคือที่อยู่ที่เผยแพร่บริการ - ลูกค้าจะใช้ URL นี้เพื่อเข้าถึงบริการ แหล่งที่มาทั้งหมดสำหรับแอปพลิเคชันเซิร์ฟเวอร์มีให้ที่นี่ -
//Server.java
package com.tutorialspoint.helloworld;
import javax.xml.ws.Endpoint;
import org.apache.cxf.ext.logging.LoggingFeature;
public class Server {
public static void main(String[] args) throws Exception {
HelloWorldPortType implementor = new HelloWorldImpl();
Endpoint.publish("http://localhost:9090/HelloServerPort",
implementor,
new LoggingFeature());
System.out.println("Server ready...");
Thread.sleep(5 * 60 * 1000);
System.out.println("Server exiting");
System.exit(0);
}
}
ในการสร้างคลาสเซิร์ฟเวอร์นี้คุณจะต้องเพิ่มโปรไฟล์การสร้างในไฟล์ pom.xml. ดังแสดงด้านล่าง -
<profile>
<id>server</id>
<build>
<defaultGoal>test</defaultGoal>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>
com.tutorialspoint.helloworld.Server
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.3.0</version>
</dependency>
</dependencies>
</profile>
โปรดทราบว่าชื่อแบบเต็มของไฟล์ Serverคลาสถูกระบุในการกำหนดค่า นอกจากนี้แท็กอ้างอิงยังระบุว่าเราจะใช้เว็บเซิร์ฟเวอร์ท่าเทียบเรือในตัวเพื่อปรับใช้แอปพลิเคชันเซิร์ฟเวอร์
การปรับใช้เซิร์ฟเวอร์
สุดท้ายในการปรับใช้แอ็พพลิเคชันเซิร์ฟเวอร์คุณจะต้องทำการปรับเปลี่ยนอีกครั้งใน pom.xml เพื่อตั้งค่าแอปพลิเคชันของคุณเป็นเว็บแอปพลิเคชัน รหัสที่คุณต้องเพิ่มลงในไฟล์pom.xml ได้รับด้านล่าง -
<defaultGoal>install</defaultGoal>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
<webResources>
<resource>
<directory>src/main/resources</directory>
<targetPath>WEB-INF</targetPath>
<includes>
<include>*.wsdl</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</pluginManagement>
ก่อนที่คุณจะปรับใช้แอปพลิเคชันคุณต้องเพิ่มไฟล์อีกสองไฟล์ในโปรเจ็กต์ของคุณ สิ่งเหล่านี้แสดงในภาพหน้าจอด้านล่าง -
ไฟล์เหล่านี้เป็นไฟล์มาตรฐาน CXF ซึ่งกำหนดการแม็ปสำหรับ CXFServlet. รหัสภายในweb.xml ไฟล์จะแสดงที่นี่สำหรับการอ้างอิงอย่างรวดเร็วของคุณ -
//cxf-servlet.xml
<web-app xmlns = "http://java.sun.com/xml/ns/javaee"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" version="2.5"
xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>cxf</display-name>
<servlet>
<description>Apache CXF Endpoint</description>
<display-name>cxf</display-name>
<servlet-name>cxf</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>60</session-timeout>
</session-config>
</web-app>
ใน cxf-servlet.xmlคุณประกาศคุณสมบัติสำหรับปลายทางของบริการของคุณ สิ่งนี้แสดงในข้อมูลโค้ดด้านล่าง -
<beans ...>
<jaxws:endpoint xmlns:helloworld = "http://tutorialspoint.com/"
id="helloHTTP"
address = "http://localhost:9090/HelloServerPort"
serviceName = "helloworld:HelloServiceService"
endpointName = "helloworld:HelloServicePort">
</jaxws:endpoint>
</beans>
ที่นี่เรากำหนดรหัสสำหรับปลายทางบริการของเราที่อยู่ที่จะให้บริการชื่อบริการและชื่อปลายทาง ตอนนี้คุณเข้าใจแล้วว่าบริการของคุณได้รับการกำหนดเส้นทางและประมวลผลโดย servlet CXF อย่างไร
pom.xml สุดท้าย
pom.xmlรวมการอ้างอิงเพิ่มเติมอีกเล็กน้อย แทนที่จะอธิบายการอ้างอิงทั้งหมดเราได้รวมเวอร์ชันสุดท้ายของ pom.xml ไว้ด้านล่าง -
<?xml version="1.0" encoding = "UTF-8"?>
<project xmlns = "http://maven.apache.org/POM/4.0.0"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.tutorialspoint</groupId>
<artifactId>cxf-wsdl</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<build>
<defaultGoal>install</defaultGoal>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<webXml>src/main/webapp/WEB-INF/web.xml</webXml>
<webResources>
<resource>
<directory>src/main/resources</directory>
<targetPath>WEB-INF</targetPath>
<includes>
<include>*.wsdl</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-codegen-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>generate-sources</id>
<phase>generate-sources</phase>
<configuration>
<wsdlOptions>
<wsdlOption>
<wsdl>src/main/resources/Hello.wsdl</wsdl>
<faultSerialVersionUID>1</faultSerialVersionUID>
</wsdlOption>
</wsdlOptions>
</configuration>
<goals>
<goal>wsdl2java</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>server</id>
<build>
<defaultGoal>test</defaultGoal>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>
com.tutorialspoint.helloworld.Server
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.3.0</version>
</dependency>
</dependencies>
</profile>
<profile>
<id>client</id>
<build>
<defaultGoal>test</defaultGoal>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>
com.tutorialspoint.helloworld.Client
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-management</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-features-metrics</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf.xjc-utils</groupId>
<artifactId>cxf-xjc-runtime</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-features-logging</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.8.0-beta2</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.3.0</version>
</dependency>
</dependencies>
</project>
โปรดทราบว่ายังมีโปรไฟล์สำหรับการสร้างไคลเอ็นต์ซึ่งเราจะเรียนรู้ในเร็ว ๆ นี้ในส่วนต่อไป
เรียกใช้บริการ HelloWorld
ตอนนี้คุณพร้อมที่จะเรียกใช้เว็บแอปแล้ว ในหน้าต่างคำสั่งให้รันสคริปต์บิลด์โดยใช้คำสั่งต่อไปนี้
mvn clean install
สิ่งนี้จะสร้างคลาส Apache CXF ที่เหมาะสมจาก wsdl ของคุณรวบรวมคลาส Apache CXF ของคุณปรับใช้เซิร์ฟเวอร์บนเซิร์ฟเวอร์ท่าเทียบเรือแบบฝังและเรียกใช้แอปพลิเคชันของคุณ
คุณจะเห็นข้อความต่อไปนี้บนคอนโซล -
INFO: Setting the server's publish address to be
http://localhost:9090/HelloServerPort
Server ready...
ก่อนหน้านี้คุณสามารถทดสอบเซิร์ฟเวอร์ได้โดยเปิด URL ของเซิร์ฟเวอร์ในเบราว์เซอร์ของคุณ
เนื่องจากเราไม่ได้ระบุการดำเนินการใด ๆ มีเพียงข้อความแสดงข้อผิดพลาดเท่านั้นที่ถูกส่งกลับไปยังเบราว์เซอร์โดยแอปพลิเคชันของเรา ตอนนี้ลองเพิ่มไฟล์?wsdl ไปยัง URL ของคุณและคุณจะเห็นผลลัพธ์ต่อไปนี้ -
แอปพลิเคชันเซิร์ฟเวอร์ของเราจึงทำงานตามที่คาดไว้ คุณสามารถใช้ SOAP Client เช่นPostman อธิบายไว้ก่อนหน้านี้เพื่อทดสอบบริการของคุณเพิ่มเติม
ส่วนถัดไปของบทช่วยสอนนี้คือการเขียนลูกค้าที่ใช้บริการของเรา
การพัฒนาลูกค้า
การเขียนไคลเอ็นต์ในแอปพลิเคชัน CXF มีความสำคัญพอ ๆ กับการเขียนเซิร์ฟเวอร์ นี่คือรหัสที่สมบูรณ์สำหรับไคลเอนต์ที่โดยพื้นฐานแล้วประกอบด้วยเพียงสามบรรทัดส่วนที่เหลือของบรรทัดเพียงแค่พิมพ์ข้อมูลบริการให้กับผู้ใช้
//Client.java
package com.tutorialspoint.helloworld;
public class Client {
public static void main(String[] args) throws Exception {
//Create the service client with its default wsdlurl
HelloWorldService helloServiceService = new HelloWorldService();
System.out.println("service: " +
helloServiceService.getServiceName());
System.out.println("wsdl location: " +
helloServiceService.getWSDLDocumentLocation());
HelloWorldPortType helloService =
helloServiceService.getHelloWorldPort();
System.out.println(helloService.greetings
(System.getProperty("user.name")));
}
}
ที่นี่เราสร้างอินสแตนซ์ของบริการของเรา HelloWorldServiceรับพอร์ตโดยการโทร getHelloWorldPort วิธีการแล้วส่งไฟล์ greetingsส่งข้อความถึงมัน เรียกใช้ไคลเอนต์และคุณจะเห็นผลลัพธ์ต่อไปนี้ -
service: {http://helloworld.tutorialspoint.com/}HelloWorldService
wsdl location: file:/Users/drsarang/Desktop/tutorialpoint/cxf-
wsdl/src/main/resources/Hello.wsdl
hi drsarang
จนถึงตอนนี้คุณได้เรียนรู้วิธีใช้ CXF กับสถาปัตยกรรม Apache CXF-First และ WSDL-First ในแนวทาง Apache CXF-First คุณใช้ POJO กับServerFactoryBeanคลาสจากไลบรารี CXF เพื่อสร้างเซิร์ฟเวอร์ เพื่อสร้างไคลเอนต์ที่คุณใช้ClientProxyFactoryBeanคลาสจากไลบรารี CXF ในแนวทาง WSDL-First คุณใช้ไฟล์Endpointคลาสเพื่อเผยแพร่บริการที่ URL ที่ต้องการและผู้ใช้งานที่ระบุ ตอนนี้คุณสามารถขยายเทคนิคเหล่านี้เพื่อรวมโปรโตคอลและการขนส่งที่แตกต่างกัน
ก่อนดำเนินการต่อในบทนี้เราคิดว่าคุณรู้วิธีเขียนเว็บเซอร์วิส RESTful ใน Java แล้ว ฉันจะแสดงวิธีใช้ CXF กับ JAX-RS นี้ (Java API สำหรับ RESTful Web Services) เราจะสร้างบริการเว็บที่เก็บรายชื่อภาพยนตร์ล่าสุด เมื่อผู้ใช้ร้องขอภาพยนตร์เขาจะระบุ ID ภาพยนตร์ในคำขอของเขาเซิร์ฟเวอร์จะค้นหาภาพยนตร์และส่งคืนให้กับไคลเอ็นต์ ในกรณีที่ไม่สำคัญของเราเราจะส่งคืนชื่อภาพยนตร์ให้กับไคลเอนต์ไม่ใช่ไฟล์ MP4 ไบนารีจริง ให้เราเริ่มสร้างแอปพลิเคชัน JAX-RS
การประกาศองค์ประกอบภาพยนตร์
เราจะประกาศองค์ประกอบรูท XML ที่เรียกว่า Movie สำหรับเก็บ id และชื่อของภาพยนตร์ที่กำหนด องค์ประกอบถูกประกาศในไฟล์ชื่อ Movie.java เนื้อหาของไฟล์แสดงที่นี่ -
//Movie.java
package com.tutorialspoint.cxf.jaxrs.movie;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "Movie")
public class Movie {
private long id;
private String name;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
หมายเหตุการใช้ XmlRootElement แท็กเพื่อประกาศองค์ประกอบ XML สำหรับไฟล์ Movieแท็ก ต่อไปเราจะสร้างบริการที่เก็บรายชื่อภาพยนตร์ไว้ในฐานข้อมูล
การสร้างฐานข้อมูลบริการภาพยนตร์
ในการจัดเก็บรายชื่อภาพยนตร์เราใช้ Java ที่ให้มา Mapที่เก็บคู่คีย์ - ค่า หากรายการมีขนาดใหญ่คุณจะใช้ที่เก็บฐานข้อมูลภายนอกซึ่งจะจัดการได้ง่ายขึ้น ในกรณีเล็กน้อยของเราเราจะจัดเก็บภาพยนตร์เพียงห้าเรื่องในฐานข้อมูลของเรา รหัสสำหรับคลาส MovieService ได้รับด้านล่าง -
//MovieService.java
package com.tutorialspoint.cxf.jaxrs.movie;
import java.util.HashMap;
import java.util.Map;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
@Path("/movieservice/")
@Produces("text/xml")
public class MovieService {
long currentId = 123;
Map<Long, Movie> movies = new HashMap<>();
public MovieService() {
init();
}
@GET
@Path("/movie/{id}/")
public Movie getMovie(@PathParam("id") String id) {
long idNumber = Long.parseLong(id);
return movies.get(idNumber);
}
final void init() {
Movie c1 = new Movie();
c1.setName("Aquaman");
c1.setId(1001);
movies.put(c1.getId(), c1);
Movie c2 = new Movie();
c2.setName("Mission Imposssible");
c2.setId(1002);
movies.put(c2.getId(), c2);
Movie c3 = new Movie();
c3.setName("Black Panther");
c3.setId(1003);
movies.put(c3.getId(), c3);
Movie c4 = new Movie();
c4.setName("A Star is Born");
c4.setId(1004);
movies.put(c4.getId(), c4);
Movie c5 = new Movie();
c5.setName("The Meg");
c5.setId(1005);
movies.put(c5.getId(), c5);
}
}
โปรดทราบว่าเราใช้คำอธิบายประกอบสองรายการต่อไปนี้เพื่อระบุเส้นทาง URL สำหรับบริการภาพยนตร์ของเราและประเภทการส่งคืน -
@Path("/movieservice/")
@Produces("text/xml")
เราใช้คำอธิบายประกอบ @GET และ @Path เพื่อระบุ URL สำหรับคำขอ GET ดังนี้ -
@GET
@Path("/movie/{id}/")
ฐานข้อมูลภาพยนตร์นั้นเริ่มต้นด้วยเมธอด init ซึ่งเราจะเพิ่มรายการภาพยนตร์ห้ารายการลงในฐานข้อมูล
งานต่อไปของเราคือการเขียนโปรแกรมเซิร์ฟเวอร์
กำลังพัฒนาเซิร์ฟเวอร์
ในการสร้างเซิร์ฟเวอร์เราใช้ CXF ที่ให้มา JAXRSServerFactoryBean ชั้นเรียน.
JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean();
เราตั้งค่าคลาสทรัพยากรโดยเรียกไฟล์ setResourceClasses วิธี.
factory.setResourceClasses(Movie.class);
factory.setResourceClasses(MovieService.class);
เราตั้งค่าผู้ให้บริการโดยโทรไปที่ไฟล์ setResourceProvider วิธี.
factory.setResourceProvider(MovieService.class,
new SingletonResourceProvider(new MovieService()));
เราตั้งค่าที่ต้องการ publish ที่อยู่โดยโทร aetAddress วิธีการ -
factory.setAddress("http://localhost:9000/");
สุดท้ายเราเผยแพร่เซิร์ฟเวอร์โดยเรียกใช้เมธอด create บนไฟล์ factory ตัวอย่าง.
factory.create();
รหัสทั้งหมดสำหรับแอปพลิเคชันเซิร์ฟเวอร์ได้รับด้านล่าง -
//Server.java
package com.tutorialspoint.cxf.jaxrs.movie;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
public class Server {
public static void main(String[] args) throws Exception {
JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean();
factory.setResourceClasses(Movie.class);
factory.setResourceClasses(MovieService.class);
factory.setResourceProvider(MovieService.class,
new SingletonResourceProvider(new MovieService()));
factory.setAddress("http://localhost:9000/");
factory.create();
System.out.println("Server ready...");
Thread.sleep(5 * 60 * 1000);
System.out.println("Server exiting ...");
System.exit(0);
}
}
pom.xml สุดท้าย
เราได้รวมเวอร์ชันสุดท้ายของ pom.xml ไว้ด้านล่าง -
<?xml version = "1.0" encoding = "UTF-8"?>
<project xmlns = "http://maven.apache.org/POM/4.0.0"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.tutorialspoint</groupId>
<artifactId>cxf-jaxrs</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<profiles>
<profile>
<id>server</id>
<build>
<defaultGoal>test</defaultGoal>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>
com.tutorialspoint.cxf.jaxrs.movie.Server
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.3.0</version>
</dependency>
</dependencies>
</profile>
<profile>
<id>client</id>
<build>
<defaultGoal>test</defaultGoal>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>
com.tutorialspoint.cxf.jaxrs.movie.Client
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>jakarta.ws.rs</groupId>
<artifactId>jakarta.ws.rs-api</artifactId>
<version>2.1.5</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.7</version>
</dependency>
</dependencies>
</project>
การพัฒนาลูกค้า
การเขียนไคลเอ็นต์ RS เป็นเรื่องเล็กน้อย เราเพียงแค่สร้างออบเจ็กต์ URL และเปิดสตรีม เราใช้คลาส IOUtils ที่ให้มาของ CXF เพื่อคัดลอกเนื้อหาของอินพุตสตรีมไปยังสตรีมภายในเครื่อง
URL url = new URL("http://localhost:9000/movieservice/movie/1002");
try (InputStream instream = url.openStream();
CachedOutputStream outstream = new CachedOutputStream()) {
IOUtils.copy(instream, outstream);
}
รหัสทั้งหมดสำหรับแอปพลิเคชันไคลเอนต์ได้รับด้านล่าง -
//Client.java
package com.tutorialspoint.cxf.jaxrs.movie;
import java.io.InputStream;
import java.net.URL;
import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.io.CachedOutputStream;
public class Client {
public static void main(String[] args) throws Exception {
URL url = new URL("http://localhost:9000/movieservice/movie/1002");
try (InputStream instream = url.openStream();
CachedOutputStream outstream = new CachedOutputStream()) {
IOUtils.copy(instream, outstream);
String str = outstream.getOut().toString();
System.out.println(str);
}
}
}
การทดสอบแอปพลิเคชัน JAX-RS
เรียกใช้เซิร์ฟเวอร์โดยใช้คำสั่งต่อไปนี้ในหน้าต่างบรรทัดคำสั่ง -
mvn -Pserver
ตอนนี้คุณจะเห็นข้อความต่อไปนี้บนคอนโซล -
INFO: Setting the server's publish address to be http://localhost:9000
ตอนนี้เปิดเบราว์เซอร์ของคุณและพิมพ์ URL ต่อไปนี้ -
http://localhost:9000/movieservice/movie/1002
คุณจะเห็นสิ่งต่อไปนี้ในหน้าต่างเบราว์เซอร์
คุณสามารถเรียกใช้บริการโดยใช้แอ็พพลิเคชันไคลเอนต์ Java ที่เราได้พัฒนาขึ้นโดยรันคำสั่งต่อไปนี้ในหน้าต่างบรรทัดคำสั่งแยกต่างหาก
mvn -Pclient
คุณจะเห็นผลลัพธ์ต่อไปนี้ -
<?xml version="1.0" encoding = "UTF-8" standalone="yes"?>
<Movie><id>1002</id><name>Mission Imposssible</name></Movie>
ตัวอย่าง CXF มีหลายตัวอย่างเกี่ยวกับวิธีใช้ CXF กับ JAX-RS ผู้อ่านที่สนใจควรศึกษาตัวอย่างเหล่านี้
ดังที่ได้กล่าวไว้ก่อนหน้านี้คุณสามารถใช้ CXF กับการขนส่ง JMS ในกรณีนี้ไคลเอนต์จะส่งข้อความ JMS ไปยัง Messaging Server ที่รู้จัก แอปพลิเคชันเซิร์ฟเวอร์ของเรากำลังฟังเซิร์ฟเวอร์การส่งข้อความอย่างต่อเนื่องสำหรับข้อความขาเข้า เมื่อข้อความมาถึงระบบจะประมวลผลข้อความดำเนินการตามคำขอของไคลเอ็นต์และส่งการตอบกลับเป็นข้อความอื่นไปยังไคลเอ็นต์
ก่อนหน้านี้เราจะสร้างแอปพลิเคชันเซิร์ฟเวอร์ตัวอย่างก่อนที่มีวิธีการเว็บเอกพจน์ที่เรียกว่า sayHi.
การสร้างอินเทอร์เฟซบริการ
อินเทอร์เฟซบริการสำหรับ HelloWorld แสดงบริการที่นี่ -
//HelloWorld.java
package com.tutorialspoint.service;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
@WebService
public interface HelloWorld {
@WebMethod
String sayHi(@WebParam(name = "name") String name);
}
การใช้บริการ
การใช้งานอินเทอร์เฟซบริการกำหนดไว้ดังนี้ -
//HelloWorldImpl.java
package com.tutorialspoint.service.impl;
import javax.jws.WebService;
import com.tutorialspoint.service.HelloWorld;
@WebService
public class HelloWorldImpl implements HelloWorld {
@Override
public String sayHi(String name) {
return "Hello " + name;
}
}
การนำไปใช้เพียงส่งคืนข้อความสวัสดีให้กับผู้ใช้ อย่างที่คุณเห็นอินเทอร์เฟซและการใช้งานนั้นคล้ายกับโครงการก่อนหน้านี้ทั้งหมดในบทช่วยสอนนี้ที่คุณได้ศึกษาจนถึงตอนนี้
ตอนนี้ประเด็นที่สำคัญที่สุดคือการสร้างแอปพลิเคชันเซิร์ฟเวอร์ที่ตั้งค่าคิวข้อความและรับฟังข้อความขาเข้าต่อไป
การสร้างเซิร์ฟเวอร์
ในแอปพลิเคชันเซิร์ฟเวอร์ก่อนอื่นเราสร้างไฟล์ JMS จุดสิ้นสุดดังนี้ -
private static final String JMS_ENDPOINT_URI =
"jms:queue:test.cxf.jmstransport.queue?timeToLive=1000"
+ "&jndiConnectionFactoryName=ConnectionFactory"
+ "&jndiInitialContextFactory"
+ "= org.apache.activemq.jndi.ActiveMQInitialContextFactory"
+ "&jndiURL = tcp://localhost:61616";
โปรดทราบว่าเราตั้งค่าคิวบนพอร์ตที่ระบุซึ่งมีอายุการใช้งานตามระยะเวลาที่กำหนด ตอนนี้เราสร้างบริการส่งข้อความโดยการสร้างอินสแตนซ์org.apache.activemq.broker.BrokerServiceชั้นเรียน. นี่คือคลาสเซิร์ฟเวอร์สำหรับActiveMQ เซิร์ฟเวอร์การส่งข้อความ
BrokerService broker = new BrokerService();
คุณสามารถใช้เซิร์ฟเวอร์การส่งข้อความอื่น ๆ ที่คุณเลือกนอกเหนือจาก ActiveMQ. ตอนนี้เราเชื่อมต่อเซิร์ฟเวอร์นี้กับ URI ที่ต้องการ
broker.addConnector("tcp://localhost:61616");
เราตั้งค่าไดเร็กทอรีสำหรับจัดเก็บข้อมูลของข้อความขาเข้า -
broker.setDataDirectory("target/activemq-data");
ในที่สุดเราเริ่มเซิร์ฟเวอร์โดยใช้วิธีเริ่มต้น -
broker.start();
ต่อไปเราจะสร้างอินสแตนซ์ของถั่วบริการของเรา HelloWorld โดยใช้คลาส bean โรงงานเซิร์ฟเวอร์ตามที่ใช้ในแอปพลิเคชัน POJO ก่อนหน้านี้ของเรา -
Object implementor = new HelloWorldImpl();
JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
factory.setServiceClass(HelloWorld.class);
ต่อไปเราจะตั้งค่าจุดสิ้นสุด JMS ในโรงงานเพื่อให้โรงงานรับฟังข้อความขาเข้าต่อไป -
factory.setTransportId
(JMSSpecConstants.SOAP_JMS_SPECIFICATION_TRANSPORTID);
factory.setAddress(JMS_ENDPOINT_URI);
ในที่สุดเราก็ตั้งค่าคลาสผู้ใช้งานในโรงงานและเริ่มเรียกใช้งาน -
factory.setServiceBean(implementor);
factory.create();
ณ จุดนี้เซิร์ฟเวอร์ของคุณเริ่มทำงานแล้ว โปรดทราบว่าเนื่องจากเราใช้คลาส bean จากโรงงานในแอปพลิเคชัน POJO จึงไม่จำเป็นต้องใช้ CXFServlet และไฟล์ web.xml
รหัสแอปพลิเคชันเซิร์ฟเวอร์แบบเต็มแสดงที่นี่ -
//ServerJMS.java
package com.tutorialspoint.server;
import java.util.Collections;
import org.apache.cxf.ext.logging.LoggingFeature;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
import org.apache.cxf.transport.jms.spec.JMSSpecConstants;
import com.tutorialspoint.service.HelloWorld;
import com.tutorialspoint.service.impl.HelloWorldImpl;
import org.apache.activemq.broker.BrokerService;
public final class ServerJMS {
private static final String JMS_ENDPOINT_URI =
"jms:queue:test.cxf.jmstransport.queue?timeToLive=1000"
+ "&jndiConnectionFactoryName=ConnectionFactory"
+ "&jndiInitialContextFactory"
+ "= org.apache.activemq.jndi.ActiveMQInitialContextFactory"
+ "&jndiURL = tcp://localhost:61616";
public static void main(String[] args) throws Exception {
BrokerService broker = new BrokerService();
broker.addConnector("tcp://localhost:61616");
broker.setDataDirectory("target/activemq-data");
broker.start();
Object implementor = new HelloWorldImpl();
JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
factory.setServiceClass(HelloWorld.class);
factory.setTransportId
(JMSSpecConstants.SOAP_JMS_SPECIFICATION_TRANSPORTID);
factory.setAddress(JMS_ENDPOINT_URI);
factory.setServiceBean(implementor);
factory.setFeatures(Collections.singletonList(new LoggingFeature()));
factory.create();
System.out.println("Server ready...");
Thread.sleep(5 * 60 * 1000);
System.out.println("Server exiting");
System.exit(0);
}
}
การเพิ่มการอ้างอิง
แอ็พพลิเคชันเซิร์ฟเวอร์ที่เราสร้างขึ้นใช้เซิร์ฟเวอร์การส่งข้อความ ActiveMQ ดังนั้นคุณจะต้องเพิ่มการอ้างอิงเพิ่มเติมในโครงการของคุณ ไฟล์ pom.xml ที่สมบูรณ์จะแสดงที่นี่เพื่อให้คุณเข้าใจการอ้างอิงที่จำเป็นเพิ่มเติม
<?xml version = "1.0" encoding = "UTF-8"?>
<project xmlns = "http://maven.apache.org/POM/4.0.0"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation = "http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.tutorialspoint</groupId>
<artifactId>cxf-jms</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<profiles>
<profile>
<id>server</id>
<build>
<defaultGoal>test</defaultGoal>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>
com.tutorialspoint.server.ServerJMS
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>client</id>
<build>
<defaultGoal>test</defaultGoal>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>
com.tutorialspoint.client.ClientJMS
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-broker</artifactId>
<version>5.15.8</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-kahadb-store</artifactId>
<version>5.15.8</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-jms</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-features-logging</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.3.0</version>
</dependency>
</dependencies>
</project>
กำลังรันเซิร์ฟเวอร์
ในการเริ่มต้นรันเซิร์ฟเวอร์ดังเช่นในกรณีก่อนหน้านี้ให้พิมพ์คำสั่งต่อไปนี้ในหน้าต่างคำสั่งของคุณ -
mvn -Pserver
สิ่งนี้จะเริ่มเซิร์ฟเวอร์ข้อความ ActiveMQ ตั้งค่าคิวการส่งข้อความและสร้างบีนโรงงานที่คอยฟังคิวนี้
งานต่อไปของเราคือการสร้างแอปพลิเคชันไคลเอนต์
การสร้างลูกค้า
ในแอปพลิเคชันไคลเอนต์อันดับแรกเราตั้งค่าจุดสิ้นสุด JMS เหมือนกับที่ใช้ในแอปพลิเคชันเซิร์ฟเวอร์ -
private static final String JMS_ENDPOINT_URI =
"jms:queue:test.cxf.jmstransport.queue?timeToLive=1000"
+ "&jndiConnectionFactoryName=ConnectionFactory"
+ "&jndiInitialContextFactory"
+ " = org.apache.activemq.jndi.ActiveMQInitialContextFactory"
+ "&jndiURL = tcp://localhost:61616";
เราสร้างโรงงานเช่นเดียวกับในแอปพลิเคชัน POJO
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
เราตั้งค่า URI ปลายทางและคลาสผู้ปฏิบัติดังนี้ -
factory.setTransportId (JMSSpecConstants.SOAP_JMS_SPECIFICATION_TRANSPORTID);
factory.setAddress (JMS_ENDPOINT_URI);
HelloWorld client = factory.create(HelloWorld.class);
สุดท้ายเราเรียกวิธีการบริการและพิมพ์ผลลัพธ์ผลลัพธ์ -
String reply = client.sayHi("TutorialsPoint");
System.out.println(reply);
รหัสลูกค้าที่สมบูรณ์ได้รับด้านล่าง -
// ClientJMS.java
package com.tutorialspoint.client;
import com.tutorialspoint.service.HelloWorld;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.transport.jms.spec.JMSSpecConstants;
public final class ClientJMS {
private static final String JMS_ENDPOINT_URI =
"jms:queue:test.cxf.jmstransport.queue?timeToLive=1000"
+ "&jndiConnectionFactoryName=ConnectionFactory"
+ "&jndiInitialContextFactory"
+ " = org.apache.activemq.jndi.ActiveMQInitialContextFactory"
+ "&jndiURL = tcp://localhost:61616";
public static void main(String[] args) throws Exception {
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setTransportId(JMSSpecConstants.SOAP_JMS_SPECIFICATION_TRANSPORTID);
factory.setAddress(JMS_ENDPOINT_URI);
HelloWorld client = factory.create(HelloWorld.class);
String reply = client.sayHi("TutorialsPoint");
System.out.println(reply);
System.exit(0);
}
}
Apache CXF - บทสรุป
CXF นำเสนอแนวทางที่เป็นหนึ่งเดียวในการผสมผสานเว็บโปรโตคอลและการขนส่งที่มีอยู่ในโลกปัจจุบันสำหรับการสร้างเว็บแอปพลิเคชัน คุณได้เรียนรู้วิธีเริ่มต้นด้วยอินเทอร์เฟซ Java แบบดั้งเดิมเพื่อสร้างเว็บแอปพลิเคชันที่ใช้ CXF จากนั้นคุณได้เรียนรู้วิธีสร้างเว็บแอปพลิเคชันและไคลเอนต์โดยเริ่มต้นด้วย WSDL
WSDL จัดเตรียมการแสดง XML ของอินเทอร์เฟซบริการของคุณ คุณใช้เครื่องมือ wsdl2java เพื่อสร้างอินเตอร์เฟส Java จาก WSDL และในที่สุดก็เขียนทั้งเซิร์ฟเวอร์และไคลเอนต์โดยใช้อินเทอร์เฟซที่สร้างขึ้น บทแนะนำนี้ยังแนะนำสั้น ๆ ให้คุณใช้ CXF ในแอปพลิเคชันบริการเว็บ RESTful ของคุณ สุดท้ายนี้เรายังได้หารือกันว่า CXF สามารถใช้กับ JMS ได้อย่างไร ตอนนี้คุณสามารถอ้างถึงตัวอย่าง CXFเพื่อการศึกษาเพิ่มเติม
Note - สามารถดาวน์โหลดซอร์สโค้ดโครงการทั้งหมดได้จากที่นี่