Apache CXF 與 JMS
如前所述,您可以將 CXF 與 JMS 傳輸一起使用。在這種情況下,客戶端將向已知的 Messaging Server 傳送 JMS 訊息。我們的伺服器應用程式持續監聽訊息伺服器上的傳入訊息。當訊息到達時,它會處理訊息,執行客戶端請求並將響應作為另一條訊息傳送給客戶端。
與之前一樣,我們首先建立一個示例伺服器應用程式,該應用程式提供一個名為 sayHi 的單個 Web 方法。
建立服務介面
我們 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;
}
}
該實現簡單地向用戶返回一條 Hello 訊息。如您所見,介面及其實現類似於您迄今為止在本教程中學習的所有早期專案。
現在,最重要的點是建立一個伺服器應用程式,該應用程式設定訊息佇列並持續監聽傳入的訊息。
建立伺服器
在伺服器應用程式中,我們首先建立如下 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://:61616";
請注意,我們在指定的埠上設定了一個佇列,該佇列存在指定的時間。我們現在透過例項化 org.apache.activemq.broker.BrokerService 類來建立訊息服務。這是 ActiveMQ 訊息伺服器的伺服器類。
BrokerService broker = new BrokerService();
您可以使用除 ActiveMQ 之外的任何其他您選擇的郵件伺服器。我們現在將此伺服器連線到所需的 URI。
broker.addConnector("tcp://:61616");
我們為傳入訊息的資料儲存設定目錄:
broker.setDataDirectory("target/activemq-data");
最後,我們使用 start 方法啟動伺服器:
broker.start();
接下來,我們使用伺服器工廠 Bean 類(如我們之前在 POJO 應用程式中使用的那樣)建立服務 Bean HelloWorld 的例項:
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();
此時,您的伺服器已啟動並正在執行。請注意,由於我們使用了與 POJO 應用程式中相同的工廠 Bean 類,因此不需要 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://:61616";
public static void main(String[] args) throws Exception {
BrokerService broker = new BrokerService();
broker.addConnector("tcp://: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 訊息伺服器,設定訊息佇列並建立一個持續監聽此佇列的工廠 Bean。
我們的下一個任務是建立客戶端應用程式。
建立客戶端
在客戶端應用程式中,我們首先設定與伺服器應用程式中使用的相同的 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://: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://: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);
}
}