Apache CXF - Hướng dẫn nhanh
Trong môi trường ngày nay, bạn có thể tạo một ứng dụng dịch vụ web bằng một số tùy chọn. Bạn có thể sử dụng một hoặc nhiều giao thức chuẩn và được chấp nhận rộng rãi để liên lạc. Ví dụ SOAP , XML / HTTP, RESTful HTTP và CORBA (Kiến trúc môi giới yêu cầu đối tượng chung, rất phổ biến ngày xưa nhưng bây giờ không còn được sử dụng thường xuyên.
Bạn cũng có thể lựa chọn các phương thức truyền tải khác nhau như HTTP, JMS , JBI và lựa chọn các API giao diện người dùng như JAX-RS và JAX-WS . Có rất nhiều tùy chọn để phát triển dịch vụ web, cần có một khung dịch vụ nguồn mở để gắn tất cả các tùy chọn đã đề cập ở trên lại với nhau và đó là những gì Apache CXF làm.
Trong hướng dẫn này, bạn sẽ học cách sử dụng CXF để tạo cả dịch vụ web và ứng dụng khách sử dụng dịch vụ, bằng cách sử dụng một hoặc nhiều tùy chọn mà chúng tôi đã liệt kê ở trên. Hướng dẫn này sẽ hướng dẫn bạn toàn bộ quá trình phát triển mã cho cả máy chủ và máy khách. Vì mỗi ứng dụng chỉ có thể sử dụng một trong các tùy chọn từ mỗi danh mục, cụ thể là giao diện người dùng, giao thông vận tải và giao thức, nên khi xem xét tất cả các hoán vị và kết hợp của ba loại này, số lượng ứng dụng sẽ cao ngất ngưởng.
Hướng dẫn này thảo luận chi tiết về sự phát triển của các dự án sau:
CXF với các đối tượng Apache CXF cũ trơn (POJO)
CXF với JAX-WS
CXF với WSDL
CXF với JAX-RS
CXF với JMS
Để đơn giản, chúng tôi đã sử dụng maven với giao diện dòng lệnh của nó. Bạn có thể sử dụng IDE ưa thích của mình để tạo một dự án maven.
Trong chương tiếp theo, chúng ta hãy bắt đầu với chương đầu tiên.
Trong chương này, bạn sẽ học cách phát triển một ứng dụng web đơn giản để gửi thông điệp chào mừng đến người dùng. Một dự án dịch vụ web sử dụng mô hình WSDL . CXF cho phép bạn ẩn mô hình WSDL này bằng cách cung cấp một giao diện người dùng đơn giản để ánh xạ các API Apache CXF với WSDL bên dưới.
Trong dự án đơn giản nhất này, giao diện của dịch vụ web sẽ được hiển thị trực tiếp với máy khách và máy khách sẽ sử dụng các API Apache CXF gốc để gọi dịch vụ web.
Đầu tiên, chúng tôi sẽ tạo một dịch vụ web. Mọi dịch vụ đều có một giao diện được hiển thị cho khách hàng. Chúng tôi có thể viết giao diện này dưới dạng giao diện Apache CXF đơn giản hoặc dưới dạng tài liệu WSDL. Trong cách tiếp cận Apache CXF-First này, chúng tôi sẽ giới thiệu dịch vụ của mình thông qua giao diện Apache CXF.
Phát triển dịch vụ web
Dịch vụ mà chúng tôi sẽ tạo trên web sẽ có một phương thức web duy nhất được gọi là greetings. Phương pháp mất mộtstringnhập đối số mà chúng tôi sẽ gửi tên người dùng. Dịch vụ sẽ gửi lại một tin nhắn chào mừng đến người gọi với tên người dùng đã nhận được bao gồm trong tin nhắn.
Giao diện dịch vụ web
Để hiển thị giao diện của dịch vụ web của chúng tôi, chúng tôi sẽ tạo một giao diện Apache CXF như sau:
//HelloWorld.java
package com.tutorialspoint.cxf.pojo;
public interface HelloWorld {
String greetings(String text);
}
Giao diện chỉ có một phương thức được gọi là greetings. Máy chủ sẽ thực hiện giao diện này. Trong ứng dụng tầm thường của chúng tôi, giao diện này được hiển thị trực tiếp với máy khách. Thông thường, trong ứng dụng dịch vụ web, bạn sử dụng WSDL để mô tả giao diện dịch vụ web. Trong ứng dụng đơn giản này, chúng tôi sẽ cung cấp giao diện trực tiếp này cho nhà phát triển khách hàng. Sau đó, khách hàng sẽ gọigreetingstin nhắn trên đối tượng máy chủ. Vì vậy, trước tiên hãy để chúng tôi tạo dịch vụ web.
Triển khai dịch vụ web
Các HelloWorld giao diện được triển khai trong HelloWorldImpl Lớp Apache CXF như hình dưới đây -
//HelloWorldImpl.java
package com.tutorialspoint.cxf.pojo;
public class HelloWorldImpl implements HelloWorld {
@Override
public String greetings(String text) {
return "Hi " + text;
}
}
Các greetings phương thức nhận một tham số là string nhập, nối nó vào một tin nhắn chào mừng và trả về chuỗi kết quả cho người gọi.
Tiếp theo, chúng tôi viết ứng dụng máy chủ để lưu trữ HelloWorld dịch vụ.
Tạo máy chủ
Ứng dụng máy chủ bao gồm hai phần:
Phần đầu tiên tạo ra một nhà máy cho dịch vụ web của chúng tôi và
Phần thứ hai viết một main phương pháp khởi tạo nó.
Máy chủ sử dụng ServerFactoryBean lớp được cung cấp bởi các thư viện CXF để hiển thị HelloWorldgiao diện với khách hàng từ xa. Do đó, trước tiên chúng tôi khởi tạoServerFactoryBean và sau đó thiết lập các thuộc tính khác nhau của nó -
ServerFactoryBean factory = new ServerFactoryBean();
Chúng tôi đặt lớp dịch vụ được gọi bằng cách gọi setServiceClass phương pháp trên factory đối tượng -
factory.setServiceClass(HelloWorld.class);
Chúng tôi đặt URL để gọi dịch vụ của mình bằng cách gọi đến nhà máy setAddressphương pháp. Lưu ý rằng dịch vụ sẽ được xuất bản tại URL này.
factory.setAddress("http://localhost:5000/Hello");
Trong trường hợp này, dịch vụ được triển khai trên máy chủ nhúng và sẽ lắng nghe cổng 5000. Bạn có thể chọn bất kỳ số cổng nào bạn chọn.
Trước khi tạo nhà máy, bạn cần cho nhà máy biết về lớp thực hiện dịch vụ của chúng tôi. Điều này được thực hiện bằng cách gọisetServiceBean phương pháp trên factory đối tượng như được hiển thị ở đây -
factory.setServiceBean(new HelloWorldImpl());
Dịch vụ bean được đặt thành thể hiện của lớp triển khai dịch vụ của chúng tôi. Cuối cùng, chúng tôi tạo nhà máy bằng cách gọicreate phương pháp -
factory.create();
Bây giờ, khi chúng tôi đã phát triển nhà máy để chạy dịch vụ web của mình, chúng tôi sẽ viết tiếp main để khởi tạo nó và giữ cho nó chạy trong một thời gian.
Bây giờ, viết một main phương pháp để khởi tạo HelloServer lớp như sau -
public static void main(String[] args) throws Exception {
new HelloServer();
System.out.println("Listening on port 5000 ...");
}
Sau khi khởi tạo, HelloServerlớp sẽ tiếp tục chạy vô thời hạn. Đối với triển khai sản xuất, bạn chắc chắn sẽ giữ cho máy chủ của mình hoạt động mãi mãi. Trong tình huống hiện tại, chúng tôi sẽ kết thúc máy chủ sau một thời gian định trước như sau:
Thread.sleep(5 * 60 * 1000);
System.out.println("Server exiting ...");
System.exit(0);
Toàn bộ mã cho HelloServer lớp học được đưa ra dưới đây -
//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);
}
}
Ứng dụng máy chủ mà chúng tôi đã tạo sử dụng ServerFactoryBeanlớp từ các thư viện CXF. Bây giờ chúng ta phải đưa các thư viện này vào dự án của mình để biên dịch thành côngHelloServerlớp học. Chúng tôi sẽ sử dụngMaven để thiết lập các phụ thuộc của dự án.
Thiết lập dự án Maven
Để tạo một dự án Maven, hãy nhập lệnh sau vào cửa sổ dòng lệnh của bạn. Lưu ý rằng chúng tôi đã thử nghiệm điều này trên máy Mac. Đối với cài đặt Windows và Linux, hướng dẫn có thể khác nhau ở một số điểm.
mvn archetype:generate
Khi được hỏi về các thuộc tính, hãy nhập các giá trị sau:
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
Khi hoàn thành lệnh maven, bạn sẽ tìm thấy cấu trúc thư mục thích hợp được tạo trong thư mục hiện tại của bạn cùng với tệp pom.xml.
Cấu trúc thư mục đã tạo được hiển thị ở đây -
Bạn sẽ thêm các phụ thuộc CXF vào pom.xmlvà cũng sao chép các tệp Apache CXF đã tạo ở trên vào thư mục thích hợp của cấu trúc đã tạo maven. Để bạn sẵn sàng tham khảo, chúng tôi đã cung cấp tệp pom.xml bên dưới cho dự án mà chúng tôi đã tạo trên máy của mình.
<?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 ở trên có thể bao gồm các phụ thuộc bổ sung không liên quan đến dự án này, nhưng là bắt buộc cho dự án tiếp theo của chúng tôi trong hướng dẫn này. Dù sao, không có hại như vậy trong việc bao gồm các phụ thuộc bổ sung.
Cấu trúc thư mục dự án
Cấu trúc thư mục dự án trên máy của tôi sau khi đặt tệp Apache CXF của máy chủ và máy khách được hiển thị bên dưới để bạn tham khảo nhanh -
Máy chủ đang chạy
Để xây dựng dự án, hãy sử dụng lệnh sau trong cửa sổ dòng lệnh của bạn:
mvn clean install
Bạn có thể khởi động máy chủ bằng lệnh sau:
mvn -Pserver
Thao tác này sẽ khởi động máy chủ và bạn sẽ thấy lời nhắc sau trên bảng điều khiển -
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 ...
Bây giờ, trong cửa sổ trình duyệt của bạn, hãy chỉ định URL của dịch vụ đã xuất bản của chúng tôi. Bạn sẽ thấy kết quả sau:
Điều này xác nhận rằng dịch vụ của chúng tôi đang chạy tại cổng được chỉ định trên máy chủ cục bộ. Vì chúng tôi không chỉ địnhgreetings trong cuộc gọi của chúng tôi, thông báo lỗi SOAP được trả về trình duyệt.
Bạn có thể kiểm tra thêm dịch vụ web của mình bằng ứng dụng khách SOAP mà bạn chọn. Ở đây chúng tôi đã sử dụng Postman để kiểm tra máy chủ của chúng tôi.
Kết quả như được hiển thị ở đây -
Quan sát điều đó SOAP Requestđã được viết mã bằng tay. Sau khi đăng yêu cầu, máy chủ đã gửiSOAP Response , được hiển thị ở phần dưới cùng của ảnh chụp màn hình.
Từ đó, bạn có thể hiểu rằng CXF duy trì việc sử dụng các giao thức SOAP cho cả yêu cầu và phản hồi trong khi cung cấp cho bạn một cái nhìn thống nhất về nhiều loại công nghệ web đang tồn tại trong thế giới ngày nay. Điều này giúp đơn giản hóa đáng kể việc phát triển ứng dụng web.
Nhiệm vụ tiếp theo của chúng tôi là tạo một ứng dụng khách sẽ sử dụng dịch vụ web mà bạn đã tạo.
Tạo khách hàng
Trong ứng dụng máy chủ HelloWorldlà giao diện hiển thị dịch vụ web của chúng tôi. Bản thân dịch vụ web chỉ cung cấp một thông điệp chào mừng đơn giản cho khách hàng. Thông thường, giao diện dịch vụ web được hiển thị với thế giới bên ngoài bằng cách sử dụng WSDL (Ngôn ngữ mô tả dịch vụ web). Trong ứng dụng tầm thường này, chúng tôi sẽ hiển thị dịch vụ web của mình cho khách hàng bằng cách hiển thị trực tiếp giao diện dịch vụ và đó làHelloWorld.class.
Với mục đích này, CXF cung cấp một lớp nhà máy được gọi là ClientProxyFactoryBean cho phép chúng tôi đính kèm vào giao diện mong muốn với phiên bản gốc đã tạo.
Đầu tiên, chúng ta tạo một phiên bản factory bean như sau:
ClientProxyFactoryBean factory = new ClientProxyFactoryBean();
Chúng tôi gọi là setAddresstrên phiên bản factory bean để đặt URL mà dịch vụ web của chúng tôi có thể được gọi. Trong trường hợp của chúng tôi, chúng tôi sẽ sử dụng URL được sử dụng trong khi tạo máy chủ ở bước trước của chúng tôi -
factory.setAddress("http://localhost:5000/Hello");
Tiếp theo, chúng tôi gọi create phương pháp trên factory ví dụ để đính kèm giao diện dịch vụ của chúng tôi HelloWorld.class với nó.
HelloWorld helloServer = factory.create(HelloWorld.class);
Cuối cùng, chúng tôi gọi greetings phương pháp để gọi dịch vụ web từ xa.
System.out.println(helloServer.greetings(System.getProperty("user.name")));
Điều này sẽ in một thông điệp chào mừng trên bảng điều khiển của bạn.
Toàn bộ nguồn cho ứng dụng khách được hiển thị bên dưới:
//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")));
}
}
Đang chạy khách hàng
Đảm bảo rằng máy chủ vẫn đang chạy trên máy của bạn. Trong trường hợp đã hết thời gian, hãy khởi động lại máy chủ bằng lệnh sau:
mvn -Pserver
Bạn sẽ thấy thông báo sau trên bảng điều khiển -
Listening on port 5000 ...
Bây giờ, trước khi máy chủ hết thời gian chờ mà chúng ta đã đặt thành 5 phút, hãy mở một cửa sổ dòng lệnh khác và khởi động máy khách bằng lệnh sau:
mvn -Pclient
Bạn sẽ thấy một thông báo tương tự như sau trên dòng lệnh:
Hi tutorialspoint
Lưu ý rằng tutorialspointlà tên người dùng của chúng tôi. Bạn sẽ nhận được một lời chào với tên của chính bạn.
Trong chương tiếp theo, chúng ta sẽ học cách sử dụng CXF trong dự án JAX-WS (Apache CXF API cho Dịch vụ Web XML).
Trong ứng dụng JAX-WS này, chúng tôi sẽ sử dụng cách tiếp cận Apache CXF-first giống như ứng dụng POJO trước đó. Vì vậy, đầu tiên chúng ta sẽ tạo một giao diện cho dịch vụ web của mình.
Khai báo giao diện dịch vụ
Như trong trường hợp trước, chúng ta sẽ tạo một dịch vụ tầm thường chỉ có một phương thức giao diện được gọi là lời chào. Mã cho giao diện dịch vụ được hiển thị bên dưới:
//HelloWorld.java
package com.tutorialspoint.cxf.jaxws.helloworld;
import javax.jws.WebService;
@WebService
public interface HelloWorld {
String greetings(String text);
}
Chúng tôi chú thích giao diện bằng @WebServicenhãn. Tiếp theo, chúng tôi sẽ thực hiện giao diện này.
Triển khai giao diện web
Việc triển khai giao diện web được hiển thị ở đây -
//HelloWorldImpl.java
package com.tutorialspoint.cxf.jaxws.helloworld;
public class HelloWorldImpl implements HelloWorld {
@Override
public String greetings(String name) {
return ("hi " + name);
}
}
Phương thức chào hỏi được chú thích bằng @Overridenhãn. Phương thức này trả về một thông báo "hi" cho người gọi.
Tiếp theo, chúng tôi sẽ viết mã để phát triển máy chủ.
Máy chủ đang phát triển
Không giống như ứng dụng POJO, bây giờ chúng tôi sẽ tách giao diện bằng cách sử dụng lớp Endpoint do CXF cung cấp để xuất bản dịch vụ của chúng tôi. Điều này được thực hiện trong hai dòng mã sau:
HelloWorld implementor = new HelloWorldImpl();
Endpoint.publish(
"http://localhost:9090/HelloServerPort",
implementor,
new LoggingFeature()
);
Tham số đầu tiên của phương thức xuất bản chỉ định URL mà tại đó dịch vụ của chúng tôi sẽ được cung cấp cho khách hàng. Tham số thứ hai chỉ định lớp triển khai cho dịch vụ của chúng tôi. Toàn bộ mã cho máy chủ được hiển thị bên dưới -
//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);
}
}
Để triển khai máy chủ của chúng tôi, bạn sẽ cần thực hiện thêm một số sửa đổi đối với dự án của mình như được liệt kê bên dưới.
Triển khai máy chủ
Cuối cùng, để triển khai ứng dụng máy chủ, bạn sẽ cần thực hiện thêm một sửa đổi nữa trong pom.xml để thiết lập ứng dụng của mình dưới dạng ứng dụng web. Mã mà bạn cần thêm vàopom.xml được đưa ra dưới đây -
<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>
Trước khi triển khai ứng dụng, bạn cần thêm hai tệp nữa vào dự án của mình. Chúng được hiển thị trong ảnh chụp màn hình bên dưới -
Các tệp này là tệp tiêu chuẩn CXF xác định ánh xạ cho CXFServlet. Mã trongweb.xml tệp được hiển thị ở đây để bạn tham khảo nhanh -
//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>
bên trong cxf-servlet.xml,bạn khai báo các thuộc tính cho điểm cuối dịch vụ của bạn. Điều này được hiển thị trong đoạn mã bên dưới -
<beans ...>
<jaxws:endpoint xmlns:helloworld = "http://tutorialspoint.com/"
id = "helloHTTP"
address = "http://localhost:9090/HelloServerPort"
serviceName = "helloworld:HelloServiceService"
endpointName = "helloworld:HelloServicePort">
</jaxws:endpoint>
</beans>
Ở đây chúng tôi xác định id cho điểm cuối dịch vụ của mình, địa chỉ mà dịch vụ sẽ khả dụng, tên dịch vụ và tên điểm cuối. Bây giờ, bạn đã biết cách dịch vụ của mình được định tuyến và xử lý bởi một Servlet CXF.
Pom.xml cuối cùng
Các pom.xmlbao gồm một số phụ thuộc khác. Thay vì mô tả tất cả các phụ thuộc, chúng tôi đã đưa vào phiên bản cuối cùng của pom.xml bên dưới:
<?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>
Lưu ý rằng nó cũng bao gồm một hồ sơ để xây dựng ứng dụng khách mà chúng ta sẽ tìm hiểu trong các phần sau của hướng dẫn này.
Chạy dịch vụ HelloWorld
Bây giờ, bạn đã sẵn sàng để chạy ứng dụng web. Trong cửa sổ lệnh, chạy tập lệnh xây dựng bằng lệnh sau.
mvn clean install
mvn -Pserver
Bạn sẽ thấy thông báo sau trên bảng điều khiển -
INFO: Setting the server's publish address to be http://localhost:9090/HelloServerPort
Server ready…
Giống như trước đó, bạn có thể kiểm tra máy chủ bằng cách mở URL máy chủ trong trình duyệt của mình.
Vì chúng tôi không chỉ định bất kỳ thao tác nào, nên chỉ có một thông báo lỗi được ứng dụng của chúng tôi trả về trình duyệt.
Bây giờ, hãy thử thêm ?wsdl vào URL của bạn và bạn sẽ thấy kết quả sau:
Vì vậy, ứng dụng máy chủ của chúng tôi đang chạy như mong đợi. Bạn có thể sử dụng Ứng dụng khách SOAP chẳng hạn nhưPostman được mô tả trước đó để kiểm tra thêm dịch vụ của bạn.
Trong phần tiếp theo, chúng ta sẽ học cách viết một khách hàng sử dụng dịch vụ của chúng ta.
Đang phát triển khách hàng
Viết máy khách trong ứng dụng CXF cũng đơn giản như viết máy chủ. Đây là mã hoàn chỉnh cho máy khách -
//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"));
}
}
Ở đây, chúng tôi sử dụng CXF được cung cấp Servicelớp để liên kết với dịch vụ đã biết. Chúng tôi gọi làcreate phương pháp trên Servicelớp để lấy một thể hiện của dịch vụ. Chúng tôi đặt cổng đã biết bằng cách gọiaddPort phương pháp trên service ví dụ.
Bây giờ, chúng tôi đã sẵn sàng sử dụng dịch vụ, mà chúng tôi thực hiện trước tiên bằng cách lấy giao diện dịch vụ bằng cách gọi getPort phương pháp trên serviceví dụ. Cuối cùng, chúng tôi gọigreetings để in lời chào trên bảng điều khiển.
Bây giờ, khi bạn đã học những kiến thức cơ bản về CXF bằng cách sử dụng phương pháp Apache CXF-First, bây giờ bạn sẽ học cách sử dụng CXF với phương pháp WSDL-First trong chương tiếp theo của chúng ta.
Ứng dụng CXF-POJO mà bạn đã phát triển dẫn đến sự kết hợp rất chặt chẽ giữa máy khách và máy chủ. Việc cấp quyền truy cập trực tiếp vào giao diện dịch vụ cũng có thể gây ra các mối đe dọa bảo mật nghiêm trọng. Do đó, việc tách giữa máy khách và máy chủ thường được mong muốn, điều này đạt được bằng cách sử dụng WSDL (Ngôn ngữ mô tả dịch vụ web).
Chúng tôi viết giao diện dịch vụ web trong tài liệu WSDL dựa trên XML. Chúng tôi sẽ sử dụng một công cụ để ánh xạ WSDL này sang các giao diện Apache CXF, sau đó được triển khai và sử dụng bởi các ứng dụng máy khách và máy chủ của chúng tôi. Để cung cấp khả năng tách, bắt đầu với WSDL là một cách ưu tiên. Muốn vậy, trước tiên bạn cần học một ngôn ngữ mới - WSDL. Viết WSDL cần một cách tiếp cận cẩn thận và sẽ tốt hơn nếu bạn có thể hiểu một số về điều này trước khi bắt đầu làm việc với nó.
Trong bài học này, chúng ta sẽ bắt đầu bằng cách xác định giao diện dịch vụ web trong tài liệu WSDL. Chúng ta sẽ học cách sử dụng CXF để tạo cả ứng dụng máy chủ và ứng dụng khách bắt đầu bằng WSDL. Chúng tôi sẽ giữ cho ứng dụng đơn giản để duy trì sự tập trung vào việc sử dụng CXF. Sau khi ứng dụng máy chủ được tạo, chúng tôi sẽ xuất bản nó lên một URL mong muốn bằng cách sử dụng lớp CXF được tích hợp sẵn.
Đầu tiên, hãy mô tả WSDL mà chúng ta sẽ sử dụng.
WSDL cho HelloWorld
Dịch vụ web mà chúng tôi sẽ triển khai sẽ có một webmethod duy nhất được gọi là greetings chấp nhận một stringtham số giữ tên người dùng và trả về một thông điệp chuỗi cho người gọi sau khi thêm một thông điệp chào mừng vào tên người dùng. Toàn bộ wsdl được hiển thị bên dưới -
//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>
Lưu ý rằng việc viết một wsdl chính xác về mặt cú pháp luôn là một thách thức đối với các nhà phát triển; có rất nhiều công cụ và trình chỉnh sửa trực tuyến có sẵn để tạo wsdl. Các trình soạn thảo này yêu cầu tên của các thông báo mà bạn muốn triển khai cùng với các tham số mà bạn muốn chuyển trong một thông báo và loại thông báo trả lại mà bạn muốn ứng dụng khách của mình nhận được. Nếu bạn biết cú pháp wsdl, bạn có thể viết tay mã toàn bộ tài liệu hoặc sử dụng một trong các trình chỉnh sửa để tạo tài liệu của riêng bạn.
Trong wsdl ở trên, chúng tôi đã xác định một thông báo duy nhất được gọi là greetings. Tin nhắn được gửi đến dịch vụ được gọi làHelloWorldService nó đang chạy ở http://localhost:9090/HelloServerPort.
Với điều này, bây giờ chúng ta sẽ tiến hành phát triển máy chủ. Trước khi phát triển máy chủ, chúng ta cần tạo giao diện Apache CXF cho dịch vụ web của mình. Điều này sẽ được thực hiện từ wsdl đã cho. Để làm điều này, bạn sử dụng một công cụ có tênwsdl2java.
Plugin wsdl2java
Vì chúng tôi sẽ sử dụng maven để xây dựng dự án, bạn sẽ cần thêm plugin sau vào pom.xml tập tin.
<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>
Lưu ý rằng chúng tôi chỉ định vị trí của wsdl nộp hồ sơ như src/main/resources/Hello.wsdl. Bạn sẽ phải đảm bảo rằng bạn tạo cấu trúc thư mục thích hợp cho dự án của mình và thêmhello.wsdl tập tin vào thư mục được chỉ định.
Các wsdl2javaplugin sẽ biên dịch wsdl này và tạo các lớp Apache CXF trong một thư mục được xác định trước. Cấu trúc dự án đầy đủ được hiển thị ở đây để bạn sẵn sàng tham khảo.
Bây giờ, bạn đã sẵn sàng tạo một máy chủ bằng cách sử dụng wsdl2javacác lớp được tạo. Các lớp mà wsdl2java đã tạo được hiển thị trong hình bên dưới:
Giao diện dịch vụ đã tạo
Trong danh sách các lớp đã tạo, bạn phải nhận thấy một trong số chúng là giao diện Apache CXF - đây là HelloWorldPortType.java. Kiểm tra tệp này trong trình soạn thảo mã của bạn. Nội dung tệp được hiển thị ở đây để bạn sẵn sàng tham khảo -
//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
);
}
Lưu ý rằng giao diện chứa một phương thức được gọi là greetings. Đây là một loại tin nhắn trong wsdl của chúng tôi. Cácwsdl2javacông cụ đã thêm phương thức này vào giao diện được tạo. Bây giờ, bạn có thể hiểu rằng bất kỳ thông báo nào bạn viết trong wsdl của mình, một phương thức tương ứng sẽ được tạo trong giao diện.
Bây giờ, nhiệm vụ của bạn sẽ là thực hiện tất cả các phương thức này tương ứng với các thông báo khác nhau mà bạn đã xác định trong wsdl của mình. Lưu ý rằng trong ví dụ trước về Apache CXF-First, chúng tôi đã bắt đầu với giao diện Apache CXF cho dịch vụ web của chúng tôi. Trong trường hợp này, giao diện Apache CXF được tạo từ wsdl.
Triển khai giao diện dịch vụ
Việc triển khai giao diện dịch vụ là không đáng kể. Việc triển khai đầy đủ được hiển thị trong danh sách dưới đây -
//HelloWorldImpl.java
package com.tutorialspoint.helloworld;
public class HelloWorldImpl implements HelloWorldPortType {
@Override
public String greetings(String name) {
return ("hi " + name);
}
}
Mã triển khai phương thức giao diện duy nhất được gọi là greetings. Phương thức nhận một tham số làstring gõ, thêm trước thông báo "hi" vào nó và trả về chuỗi kết quả cho người gọi.
Tiếp theo, chúng ta sẽ viết ứng dụng máy chủ.
Máy chủ đang phát triển
Việc phát triển ứng dụng máy chủ một lần nữa lại trở nên tầm thường. Ở đây, chúng tôi sẽ sử dụng CXF được cung cấpEndpointlớp để xuất bản dịch vụ của chúng tôi. Điều này được thực hiện trong hai dòng mã sau:
HelloWorldPortType implementor = new HelloWorldImpl();
Endpoint.publish("http://localhost:9090/HelloServerPort",
implementor,
new LoggingFeature());
Đầu tiên, chúng tôi tạo một đối tượng của lớp trình triển khai dịch vụ của chúng tôi - HelloWorldImpl. Sau đó, chúng tôi chuyển tham chiếu này làm tham số thứ hai chopublishphương pháp. Tham số đầu tiên là địa chỉ mà dịch vụ được xuất bản - khách hàng sẽ sử dụng URL này để truy cập dịch vụ. Toàn bộ nguồn cho ứng dụng máy chủ được cung cấp ở đây -
//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);
}
}
Để xây dựng lớp máy chủ này, bạn sẽ cần thêm cấu hình xây dựng trong pom.xml. Điều này được hiển thị bên dưới -
<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>
Lưu ý rằng tên đủ điều kiện của Serverlớp được chỉ định trong cấu hình. Ngoài ra, thẻ phụ thuộc chỉ định rằng chúng tôi sẽ sử dụng máy chủ web cầu cảng được nhúng để triển khai ứng dụng máy chủ của chúng tôi.
Triển khai máy chủ
Cuối cùng, để triển khai ứng dụng máy chủ, bạn sẽ cần thực hiện thêm một sửa đổi nữa trong pom.xml để thiết lập ứng dụng của mình dưới dạng ứng dụng web. Mã mà bạn cần thêm vàopom.xml được đưa ra dưới đây -
<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>
Trước khi triển khai ứng dụng, bạn cần thêm hai tệp nữa vào dự án của mình. Chúng được hiển thị trong ảnh chụp màn hình bên dưới -
Các tệp này là tệp tiêu chuẩn CXF xác định ánh xạ cho CXFServlet. Mã trongweb.xml tệp được hiển thị ở đây để bạn tham khảo nhanh -
//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>
bên trong cxf-servlet.xmlbạn khai báo các thuộc tính cho điểm cuối dịch vụ của bạn. Điều này được hiển thị trong đoạn mã bên dưới -
<beans ...>
<jaxws:endpoint xmlns:helloworld = "http://tutorialspoint.com/"
id="helloHTTP"
address = "http://localhost:9090/HelloServerPort"
serviceName = "helloworld:HelloServiceService"
endpointName = "helloworld:HelloServicePort">
</jaxws:endpoint>
</beans>
Ở đây chúng tôi xác định id cho điểm cuối dịch vụ của mình, địa chỉ mà dịch vụ sẽ khả dụng, tên dịch vụ và tên điểm cuối. Bây giờ, bạn đã hiểu cách dịch vụ của bạn được định tuyến và xử lý bởi một servlet CXF.
Pom.xml cuối cùng
Các pom.xmlbao gồm một số phụ thuộc khác. Thay vì mô tả tất cả các phụ thuộc, chúng tôi đã đưa vào phiên bản cuối cùng của pom.xml bên dưới:
<?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>
Lưu ý rằng nó cũng bao gồm một hồ sơ để xây dựng khách hàng mà chúng ta sẽ sớm tìm hiểu trong các phần sau.
Chạy dịch vụ HelloWorld
Bây giờ, bạn đã sẵn sàng để chạy ứng dụng web. Trong cửa sổ lệnh, chạy tập lệnh xây dựng bằng lệnh sau.
mvn clean install
Thao tác này sẽ tạo các lớp Apache CXF thích hợp từ wsdl của bạn, biên dịch các lớp Apache CXF của bạn, triển khai máy chủ trên máy chủ cầu cảng được nhúng và chạy ứng dụng của bạn.
Bạn sẽ thấy thông báo sau trên bảng điều khiển -
INFO: Setting the server's publish address to be
http://localhost:9090/HelloServerPort
Server ready...
Như trước đây, bạn có thể kiểm tra máy chủ bằng cách mở URL máy chủ trong trình duyệt của mình.
Vì chúng tôi không chỉ định bất kỳ thao tác nào, nên chỉ có một thông báo lỗi được ứng dụng của chúng tôi trả về trình duyệt. Bây giờ, hãy thử thêm?wsdl vào URL của bạn và bạn sẽ thấy kết quả sau:
Vì vậy, ứng dụng máy chủ của chúng tôi đang chạy như mong đợi. Bạn có thể sử dụng Ứng dụng khách SOAP chẳng hạn nhưPostman được mô tả trước đó để kiểm tra thêm dịch vụ của bạn.
Phần tiếp theo của hướng dẫn này là viết một ứng dụng khách sử dụng dịch vụ của chúng tôi.
Đang phát triển khách hàng
Viết máy khách trong ứng dụng CXF cũng quan trọng như viết máy chủ. Đây là mã hoàn chỉnh cho máy khách về cơ bản chỉ bao gồm 3 dòng, các dòng còn lại chỉ in thông tin dịch vụ cho người dùng.
//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")));
}
}
Ở đây, chúng tôi chỉ cần tạo một phiên bản dịch vụ của chúng tôi HelloWorldService, lấy cổng của nó bằng cách gọi getHelloWorldPort và sau đó vượt qua greetingsnhắn cho nó. Chạy ứng dụng khách và bạn sẽ thấy kết quả sau:
service: {http://helloworld.tutorialspoint.com/}HelloWorldService
wsdl location: file:/Users/drsarang/Desktop/tutorialpoint/cxf-
wsdl/src/main/resources/Hello.wsdl
hi drsarang
Cho đến nay, bạn đã học cách sử dụng CXF với các kiến trúc Apache CXF-First và WSDL-First. Trong cách tiếp cận Apache CXF-First, bạn đã sử dụng POJO vớiServerFactoryBeanlớp từ các thư viện CXF để tạo một máy chủ. Để tạo một khách hàng bạn đã sử dụngClientProxyFactoryBeanlớp từ thư viện CXF. Trong phương pháp WSDL-First, bạn đã sử dụngEndpointlớp để xuất bản dịch vụ tại URL mong muốn và một trình triển khai được chỉ định. Bây giờ bạn có thể mở rộng các kỹ thuật này để tích hợp các giao thức và phương tiện truyền tải khác nhau.
Trước khi tiếp tục chương này, chúng tôi giả định rằng bạn biết cách viết một dịch vụ web RESTful bằng Java. Tôi sẽ chỉ cho bạn cách sử dụng CXF trên JAX-RS này (API Java cho Dịch vụ Web RESTful). Chúng tôi sẽ tạo một dịch vụ web lưu trữ danh sách các bộ phim mới nhất. Khi người dùng yêu cầu một bộ phim, anh ta chỉ định ID phim trong yêu cầu của mình, máy chủ sẽ xác định vị trí phim và trả lại cho máy khách. Trong trường hợp nhỏ của chúng tôi, chúng tôi sẽ chỉ trả lại tên phim cho máy khách chứ không phải tệp MP4 nhị phân thực. Vì vậy, chúng ta hãy bắt đầu tạo một ứng dụng JAX-RS.
Khai báo yếu tố phim
Chúng tôi sẽ khai báo một phần tử gốc XML có tên là Movie để lưu trữ id và tên của một bộ phim nhất định. Phần tử được khai báo trong tệp có tên Movie.java. Nội dung của tệp được hiển thị ở đây -
//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;
}
}
Lưu ý việc sử dụng XmlRootElement để khai báo phần tử XML cho Movienhãn. Tiếp theo, chúng ta sẽ tạo một dịch vụ chứa danh sách phim trong cơ sở dữ liệu của nó.
Tạo cơ sở dữ liệu dịch vụ phim
Để lưu danh sách phim, chúng tôi sử dụng Java được cung cấp Maplưu trữ các cặp khóa-giá trị. Nếu danh sách lớn, bạn sẽ sử dụng bộ lưu trữ cơ sở dữ liệu bên ngoài, điều này cũng sẽ dễ quản lý hơn. Trong trường hợp tầm thường của chúng tôi, chúng tôi sẽ chỉ lưu trữ năm phim trong cơ sở dữ liệu của mình. Mã cho lớp MovieService được cung cấp bên dưới:
//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);
}
}
Lưu ý rằng chúng tôi sử dụng hai chú thích sau để chỉ định đường dẫn URL cho dịch vụ phim của chúng tôi và kiểu trả về của nó -
@Path("/movieservice/")
@Produces("text/xml")
Chúng tôi sử dụng chú thích @GET và @Path để chỉ định URL cho yêu cầu GET như sau:
@GET
@Path("/movie/{id}/")
Bản thân cơ sở dữ liệu phim được khởi tạo trong phương thức init, nơi chúng tôi thêm năm mục phim vào cơ sở dữ liệu.
Nhiệm vụ tiếp theo của chúng ta là viết một ứng dụng máy chủ.
Máy chủ đang phát triển
Để tạo một máy chủ, chúng tôi sử dụng CXF được cung cấp JAXRSServerFactoryBean lớp học.
JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean();
Chúng tôi đặt các lớp tài nguyên của nó bằng cách gọi setResourceClasses phương pháp.
factory.setResourceClasses(Movie.class);
factory.setResourceClasses(MovieService.class);
Chúng tôi đặt nhà cung cấp dịch vụ bằng cách gọi đến setResourceProvider phương pháp.
factory.setResourceProvider(MovieService.class,
new SingletonResourceProvider(new MovieService()));
Chúng tôi đặt mong muốn publish địa chỉ bằng cách gọi aetAddress phương pháp -
factory.setAddress("http://localhost:9000/");
Cuối cùng, chúng tôi xuất bản máy chủ bằng cách gọi phương thức tạo trên factory ví dụ.
factory.create();
Toàn bộ mã cho ứng dụng máy chủ được cung cấp bên dưới:
//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 cuối cùng
Ở đây chúng tôi đã bao gồm phiên bản cuối cùng của pom.xml bên dưới -
<?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>
Đang phát triển khách hàng
Viết RS client là một việc không bình thường. Chúng tôi chỉ cần tạo một đối tượng URL và mở luồng của nó. Chúng tôi sử dụng lớp IOUtils do CXF cung cấp để sao chép nội dung của luồng đầu vào vào luồng cục bộ.
URL url = new URL("http://localhost:9000/movieservice/movie/1002");
try (InputStream instream = url.openStream();
CachedOutputStream outstream = new CachedOutputStream()) {
IOUtils.copy(instream, outstream);
}
Toàn bộ mã cho ứng dụng khách được cung cấp bên dưới:
//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);
}
}
}
Thử nghiệm ứng dụng JAX-RS
Chạy máy chủ bằng lệnh sau trong cửa sổ dòng lệnh:
mvn -Pserver
Bây giờ, bạn sẽ thấy thông báo sau trên bảng điều khiển -
INFO: Setting the server's publish address to be http://localhost:9000
Bây giờ, hãy mở trình duyệt của bạn và nhập URL sau:
http://localhost:9000/movieservice/movie/1002
Bạn sẽ thấy thông tin sau trong cửa sổ trình duyệt.
Bạn có thể gọi dịch vụ bằng cách sử dụng ứng dụng khách Java mà chúng tôi đã phát triển bằng cách chạy lệnh sau trong một cửa sổ dòng lệnh riêng biệt.
mvn -Pclient
Bạn sẽ thấy kết quả sau:
<?xml version="1.0" encoding = "UTF-8" standalone="yes"?>
<Movie><id>1002</id><name>Mission Imposssible</name></Movie>
Các mẫu CXF cung cấp một số ví dụ về cách sử dụng CXF với JAX-RS. Các độc giả quan tâm được khuyến khích để nghiên cứu các mẫu này.
Như đã đề cập trước đó, bạn có thể sử dụng CXF với JMS transport. Trong trường hợp này, máy khách sẽ gửi một tin nhắn JMS đến một Máy chủ Nhắn tin đã biết. Ứng dụng máy chủ của chúng tôi liên tục lắng nghe máy chủ nhắn tin cho các tin nhắn đến. Khi thông báo đến, nó sẽ xử lý thông báo, thực hiện yêu cầu của máy khách và gửi phản hồi dưới dạng một thông điệp khác đến máy khách.
Như trước đó, trước tiên chúng ta sẽ tạo một ứng dụng máy chủ mẫu cung cấp một phương thức web đơn lẻ được gọi là sayHi.
Tạo giao diện dịch vụ
Giao diện dịch vụ cho HelloWorld dịch vụ được hiển thị ở đây -
//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);
}
Dịch vụ triển khai
Việc triển khai giao diện dịch vụ được định nghĩa như sau:
//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;
}
}
Việc triển khai chỉ đơn giản là trả về một thông báo Xin chào cho người dùng. Như bạn thấy, giao diện và cách triển khai của nó tương tự như tất cả các dự án trước đó trong hướng dẫn này mà bạn đã nghiên cứu cho đến nay.
Bây giờ, đến điểm quan trọng nhất là tạo một ứng dụng máy chủ để thiết lập hàng đợi tin nhắn và tiếp tục nghe các tin nhắn đến.
Tạo máy chủ
Trong ứng dụng máy chủ, trước tiên chúng tôi tạo JMS điểm cuối như sau -
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";
Lưu ý rằng chúng tôi thiết lập một hàng đợi trên một cổng cụ thể tồn tại trong một khoảng thời gian nhất định. Bây giờ chúng tôi tạo ra một dịch vụ nhắn tin bằng cách khởi tạoorg.apache.activemq.broker.BrokerServicelớp học. Đây là một lớp máy chủ choActiveMQ máy chủ nhắn tin.
BrokerService broker = new BrokerService();
Bạn có thể sử dụng bất kỳ máy chủ nhắn tin nào khác mà bạn chọn ngoài ActiveMQ. Bây giờ chúng tôi kết nối máy chủ này với một URI mong muốn.
broker.addConnector("tcp://localhost:61616");
Chúng tôi thiết lập thư mục để lưu trữ dữ liệu của các tin nhắn đến -
broker.setDataDirectory("target/activemq-data");
Cuối cùng, chúng tôi khởi động máy chủ bằng phương pháp bắt đầu -
broker.start();
Tiếp theo, chúng tôi tạo một phiên bản của dịch vụ bean HelloWorld bằng cách sử dụng lớp bean của nhà máy máy chủ như được sử dụng trong ứng dụng POJO trước đó của chúng tôi -
Object implementor = new HelloWorldImpl();
JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
factory.setServiceClass(HelloWorld.class);
Tiếp theo, chúng tôi thiết lập điểm cuối JMS trên nhà máy để nhà máy tiếp tục lắng nghe các tin nhắn đến -
factory.setTransportId
(JMSSpecConstants.SOAP_JMS_SPECIFICATION_TRANSPORTID);
factory.setAddress(JMS_ENDPOINT_URI);
Cuối cùng, chúng tôi thiết lập lớp triển khai trong nhà máy và bắt đầu chạy nó -
factory.setServiceBean(implementor);
factory.create();
Tại thời điểm này, máy chủ của bạn đã hoạt động. Lưu ý rằng vì chúng tôi đã sử dụng lớp đậu gốc như trong ứng dụng POJO, nên không cần CXFServlet và tệp web.xml.
Mã ứng dụng máy chủ đầy đủ được hiển thị ở đây -
//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);
}
}
Thêm phụ thuộc
Ứng dụng máy chủ mà chúng tôi đã tạo sử dụng máy chủ nhắn tin ActiveMQ. Vì vậy, bạn sẽ cần thêm một vài phụ thuộc vào dự án của mình. Tệp pom.xml hoàn chỉnh được hiển thị ở đây để bạn hiểu các phụ thuộc cần thiết bổ sung.
<?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>
Máy chủ đang chạy
Để bắt đầu chạy máy chủ, như trong các trường hợp trước, hãy nhập lệnh sau vào cửa sổ lệnh của bạn:
mvn -Pserver
Thao tác này sẽ khởi động máy chủ tin nhắn ActiveMQ, thiết lập hàng đợi nhắn tin và tạo một factory bean tiếp tục lắng nghe hàng đợi này.
Nhiệm vụ tiếp theo của chúng tôi là tạo một ứng dụng khách.
Tạo khách hàng
Trong ứng dụng khách, trước tiên chúng tôi thiết lập điểm cuối JMS giống như điểm cuối được sử dụng trong ứng dụng máy chủ -
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";
Chúng tôi tạo một nhà máy như trong ứng dụng POJO.
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
Chúng tôi đặt URI điểm cuối và lớp trình triển khai như sau:
factory.setTransportId (JMSSpecConstants.SOAP_JMS_SPECIFICATION_TRANSPORTID);
factory.setAddress (JMS_ENDPOINT_URI);
HelloWorld client = factory.create(HelloWorld.class);
Cuối cùng, chúng tôi gọi phương thức dịch vụ và in kết quả đầu ra của nó -
String reply = client.sayHi("TutorialsPoint");
System.out.println(reply);
Mã khách hàng hoàn chỉnh được cung cấp bên dưới:
// 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 - Kết luận
CXF cung cấp một cách tiếp cận thống nhất để trộn-n-khớp một số giao thức web và phương tiện truyền tải tồn tại trong thế giới ngày nay để tạo các ứng dụng web. Bạn đã học cách bắt đầu với giao diện Java truyền thống để tạo ứng dụng web sử dụng CXF. Tiếp theo, bạn đã học cách tạo một ứng dụng web và ứng dụng khách của nó bắt đầu bằng WSDL.
WSDL cung cấp biểu diễn XML của giao diện dịch vụ của bạn. Bạn đã sử dụng công cụ wsdl2java để tạo giao diện Java từ WSDL và cuối cùng đã viết cả máy chủ và máy khách bằng các giao diện đã tạo. Hướng dẫn cũng giới thiệu ngắn gọn cho bạn cách sử dụng CXF trong ứng dụng dịch vụ web RESTful của bạn. Cuối cùng, chúng tôi cũng thảo luận về cách CXF có thể được sử dụng với JMS. Bây giờ bạn có thể tham khảo các mẫu CXF để nghiên cứu thêm.
Note - Toàn bộ mã nguồn của dự án có thể được tải xuống từ đây.