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 - สามารถดาวน์โหลดซอร์สโค้ดโครงการทั้งหมดได้จากที่นี่