Apache CXF 与 JAX-WS
在此 JAX-WS 应用程序中,我们将像早期的 POJO 应用程序一样使用 Apache CXF-first 方法。首先我们将为我们的网络服务创建一个界面。
声明服务接口
与前面的情况一样,我们将创建一个简单的服务,它只有一个名为greetings 的接口方法。服务接口的代码如下所示 -
//HelloWorld.java
package com.tutorialspoint.cxf.jaxws.helloworld;
import javax.jws.WebService;
@WebService
public interface HelloWorld {
String greetings(String text);
}
我们使用@WebService标签来注释该接口。接下来我们就来实现这个接口。
实施网页界面
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( "http://localhost:9090/HelloServerPort", implementor, new LoggingFeature() );
发布方法的第一个参数指定向客户端提供我们的服务的 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("http://localhost: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://www.tutorialspoint.com/"
id = "helloHTTP"
address = "http://localhost: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 http://localhost: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 = "http://localhost: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方法来获取服务的实例。我们通过调用服务实例上的addPort方法来设置已知端口。
现在,我们准备使用该服务,首先通过调用服务实例上的getPort方法来获取服务接口。最后,我们调用greetings方法在控制台上打印问候消息。
现在,您已经通过使用 Apache CXF-First 方法了解了 CXF 的基础知识,接下来您将在下一章中学习如何通过 WSDL-First 方法使用 CXF。