Apache CXF 與 JAX-WS
在這個 JAX-WS 應用中,我們將像之前的 POJO 應用一樣使用 Apache CXF 優先的方法。所以首先我們將為我們的 Web 服務建立一個介面。
宣告服務介面
和之前一樣,我們將建立一個只有名為 greetings 的一個介面方法的簡單服務。服務介面的程式碼如下所示:
//HelloWorld.java
package com.tutorialspoint.cxf.jaxws.helloworld;
import javax.jws.WebService;
@WebService
public interface HelloWorld {
String greetings(String text);
}
我們使用@WebService標籤註釋介面。接下來,我們將實現這個介面。
實現 Web 介面
Web 介面的實現如下所示:
//HelloWorldImpl.java
package com.tutorialspoint.cxf.jaxws.helloworld;
public class HelloWorldImpl implements HelloWorld {
@Override
public String greetings(String name) {
return ("hi " + name);
}
}
greetings 方法使用@Override標籤進行註釋。該方法向呼叫者返回“hi”訊息。
接下來,我們將編寫開發伺服器的程式碼。
開發伺服器
與 POJO 應用不同,我們現在將使用 CXF 提供的 Endpoint 類來發布我們的服務,從而解耦介面。這是透過以下兩行程式碼完成的:
HelloWorld implementor = new HelloWorldImpl(); Endpoint.publish( "https://:9090/HelloServerPort", implementor, new LoggingFeature() );
publish 方法的第一個引數指定我們的服務將向客戶端提供的 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("https://: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 中進行一次修改,以將您的應用程式設定為 Web 應用程式。需要新增到您的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 = "https://tutorialspoint.tw/"
id = "helloHTTP"
address = "https://:9090/HelloServerPort"
serviceName = "helloworld:HelloServiceService"
endpointName = "helloworld:HelloServicePort">
</jaxws:endpoint>
</beans>
在這裡,我們定義了服務端點的 ID、服務可用的地址、服務名稱和端點名稱。現在,您瞭解了您的服務如何由 CXF servlet 路由和處理。
最終的 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 服務
現在,您可以執行 Web 應用了。在命令視窗中,使用以下命令執行構建指令碼。
mvn clean install
mvn -Pserver
您將在控制檯中看到以下訊息:
INFO: Setting the server's publish address to be https://:9090/HelloServerPort Server ready…
和之前一樣,您可以透過在瀏覽器中開啟伺服器 URL 來測試伺服器。
由於我們沒有指定任何操作,我們的應用程式只向瀏覽器返回錯誤訊息。
現在,嘗試將?wsdl新增到您的 URL,您將看到以下輸出:
所以我們的伺服器應用程式按預期執行。您可以使用前面描述的 SOAP 客戶端(例如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 = "https://:9090/HelloServerPort";
service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING,
endpointAddress);
HelloWorld hw = service.getPort(HelloWorld.class);
System.out.println(hw.greetings("World"));
}
}
在這裡,我們使用 CXF 提供的Service類繫結到已知服務。我們在Service類上呼叫create方法以獲取服務的例項。我們透過在service例項上呼叫addPort方法來設定已知埠。
現在,我們可以使用該服務了,我們首先透過在service例項上呼叫getPort方法來獲取服務介面。最後,我們呼叫我們的greetings方法以在控制檯中列印問候訊息。
現在,您已經學習了使用 Apache CXF 優先方法的 CXF 基礎知識,您將在下一章學習如何在我們的 WSDL 優先方法中使用 CXF。