CXF 与 JMS
如前所述,您可以将 CXF 与 JMS 传输一起使用。在这种情况下,客户端将向已知的消息传递服务器发送 JMS 消息。我们的服务器应用程序不断地侦听消息服务器以获取传入消息。当消息到达时,它处理消息,执行客户端请求并将响应作为另一条消息发送给客户端。
如前所述,我们将首先创建一个示例服务器应用程序,该应用程序提供一个名为
sayHi 的单一 Web 方法。
创建服务接口
我们的
HelloWorld 服务的服务接口如下所示-
//HelloWorld.java
package com.lidihuo.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.lidihuo.service.impl;
import javax.jws.WebService;
import com.lidihuo.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://localhost:61616";
请注意,我们在指定端口上设置了一个队列,该队列存在指定的时间。我们现在通过实例化
org.apache.activemq.broker.BrokerService 类来创建一个消息服务。这是
ActiveMQ 消息服务器的服务器类。
BrokerService broker = new BrokerService();
您可以使用除
ActiveMQ 以外的任何其他消息服务器。我们现在将此服务器连接到所需的 URI。
broker.addConnector("tcp://localhost:61616");
我们为传入消息的数据存储设置目录-
broker.setDataDirectory("target/activemq-data");
最后,我们使用 start 方法启动服务器-
接下来,我们使用我们之前的 POJO 应用程序中使用的服务器工厂 bean 类创建服务 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.lidihuo.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.lidihuo.service.HelloWorld;
import com.lidihuo.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.lidihuo</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.lidihuo.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.lidihuo.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>
运行服务器
要开始运行服务器,就像之前的情况一样,在命令窗口中键入以下命令-
这将启动 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://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("Lidihuo");
System.out.println(reply);
完整的客户端代码如下-
// ClientJMS.java
package com.lidihuo.client;
import com.lidihuo.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("Lidihuo");
System.out.println(reply);
System.exit(0);
}
}