带有 JMS 的 Apache CXF
如前所述,你可以将 CXF 与 JMS 传输一起使用。在这种情况下,客户端将向已知的 Messaging Server 发送 JMS 消息。我们的服务器应用程序不断地监听消息服务器以获取传入消息。当消息到达时,它处理消息,执行客户端请求并将响应作为另一条消息发送给客户端。
如前所述,我们将首先创建一个示例服务器应用程序,该应用程序提供一个名为 sayHi .
创建服务接口
我们的服务接口 你好世界 服务显示在这里:
// HelloWorld.java package com.newbiego.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.newbiego.service.impl; import javax.jws.WebService; import com.newbiego.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 类:
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.newbiego.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.newbiego.service.HelloWorld; import com.newbiego.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.newbiego</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.newbiego.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.newbiego.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("NewbieGo"); System.out.println(reply);
完整的客户端代码如下:
// ClientJMS.java package com.newbiego.client; import com.newbiego.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("NewbieGo"); System.out.println(reply); System.exit(0); } }