
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://127.0.0.1:61616";
请注意,我们在指定的端口上设置了一个队列,该队列存在指定的时间。我们现在通过实例化 org.apache.activemq.broker.BrokerService 类来创建消息服务。这是 ActiveMQ 消息服务器的服务器类。
BrokerService broker = new BrokerService();
您可以使用除 ActiveMQ 之外的任何其他您选择的邮件服务器。我们现在将此服务器连接到所需的 URI。
broker.addConnector("tcp://127.0.0.1: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://127.0.0.1:61616"; public static void main(String[] args) throws Exception { BrokerService broker = new BrokerService(); broker.addConnector("tcp://127.0.0.1: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://127.0.0.1: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://127.0.0.1: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); } }