Apache-CXF-利用spring写一个服务

Apache CXF -利用Spring写一个服务

Writing a service with Spring

环境搭建 | Setting up your build

推荐使用 Apache Maven 建立web service项目. 点击超链接查看本实例的 Maven pom.xml 配置.

Maven Dependency Pluginmvn dependency:listmvn dependency:tree 命令可以查看项目所用的依赖。

<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>3.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
</dependency>
</dependencies>

编写服务

首先编写服务的接口,其有一个sayHi方法向提交姓名者输出“Hello”

package demo.spring.service;
import javax.jws.WebService;
@WebService
public interface HelloWord{
String sayHi(String text);
}

然后写实现类

package demo.spring.service;
import jjavax.jws.WebService;
@WebService(endpointInterface = "demo.spring.service.HelloWorld")
public class HelloWorld implements HelloWorld{
public String sayHi(String text){
System.out.println("sayHi called!");
return "Hello " + text;
}
}

实现类的 @WebService 注解使 CXF 知道创建WSDL时使用哪个接口。

声明服务beans | Declaring your server beans

CXF包含对Spring的XML配置的支持。对于 JAX-WS 端的应用,利用<jaxws:endpoint> bean来建立一个 服务端终端(endpoint)。

WEB-INF下面创建声明一个端点bean的cxf-servlet.xml文件

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml"/>
<import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>
<jaxws:endpoint id="helloWorld" implementor="demo.spring.service.HelloWorldImpl" address="/HelloWorld"/>
</beans>

如果想引用一个Spring管理的bean,可以这样写

<bean id="hello" class="demo.spring.service.HelloWorldImpl" />
<jaxws:endpoint id="helloWorld" implementor="#hello" address="/HelloWorld" />

这个bean使用了下列属性:

  • id 指定了bean在spring环境中的 id
  • implementor指定了实现类
  • address指定了服务的网络地址,此地址只能是一个相对地址。 这是因为CXF不知道war的名称以及servlet容器监听的端口,CXF将会在运行时随请求url一起更新终端地址。

为了让一个bean名称而非一个类名作为implementor, 只需要在提供的bean名称之前添加#。如implementor="#myBean".

更多信息查看 JAX-WS Configuration.

设置Servlet环境 | Setting up the Servlet

由于我们采用了默认的 “cxf-servlet.xml” 文件,我们也可以采用被其他例子使用的 default web.xml

若我们使用了任意命名的配置文件,如beans.xml,那么我们需要加入下列元素:

Spring的 ContextLoaderLister. 其用来启动 Spring 并明确地加载指定的配置文件. 我们可以通过 context-param 元素来指定文件地址,如.

<web-app ...>
...
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/beans.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
</web-app>

值的注意的一点是,选定的终端bean的地址必须是servlet监听的内容。例如,如果servlet注册了"/some-services/*", 但我们的地址是"/more-services/HelloWorld",那么 CXF 是无法获取到请求的.

创建客户端(简便方法) | Create a Client (Easy Way)

就像服务端使用的<jaxws:endpoint> ,客户端可以使用 <jaxws:client> . 你需要给一个bean名称,一个服务接口和一个服务URL, 它会根据指定的名称创建一个bean,实现这个服务接口,调用远程SOAP服务:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<jaxws:client id="helloClient" serviceClass="demo.spring.HelloWorld" address="http://localhost:9002/HelloWorld" />
</beans>

可以在其他任意的Spring bean中注入(inject"helloClient"bean 或者手动去 Spring的应用上下文中查找:

ApplicationContext context = ...; // your Spring ApplicationContext
HelloWorld client = (HelloWorld) context.getBean("helloClient");

可以利用 <jaxws:client> 元素做更多复杂的使其( sophisticated things),如添加一个嵌套的标签来给客户端附加 JAX-WS Handlers 或 CXF Interceptors . 查看 JAX-WS Configuration.

创建客户端(更复杂方法)| Create a Client (More Manual Way)

CXF 包含一个可以从服务接口创建客户端的 JaxWsProxyFactory bean。你只需简单 地告诉它你的服务类服务URL是什么,然后就可以利用 JaxWsProxyFactory 的 create()方法来创建客户端。

例子:

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schema/jaxws.xsd">
<bean id="client" class="demo.spring.service.HelloWorld" factory-bean="clientFactory" factory-method="create"/>
<bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="demo.spring.service.HelloWorld"/>
<property name="address" value="http://localhost:9002/services/HelloWorld"/>
</bean>
</beans>

若你打算访问你的客户端,你只需要将它从Spring上下文中取出来 (或更好的方法是,利用Spring将其注入到你的应用程序中):

ApplicationContext context = ...; // your Spring ApplicationContext
HelloWorld client = (HelloWorld) context.getBean("client");

客户端代码位于Client.java

package demo.spring.client;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import demo.spring.service.HelloWorld;
public final class Client {
private Client() {
}
public static void main(String args[]) throws Exception {
// START SNIPPET: client
ClassPathXmlApplicationContext context
= new ClassPathXmlApplicationContext(new String[] {"client-beans.xml"});
HelloWorld client = (HelloWorld)context.getBean("client");
String response = client.sayHi("Joe");
System.out.println("Response: " + response);
System.exit(0);
// END SNIPPET: client
}
}

有些应用情景会需要更多额外的配置 (且不是上述的 <jaxws:client> 语法). 查看 JAX-WS Configuration.

进一步操作 | Advanced Steps

更多使用Spring 的信息可以阅读 Configuration 和User’s Guided Spring 部分。

文章目录
  1. 1. Apache CXF -利用Spring写一个服务
    1. 1.1. 环境搭建 | Setting up your build
    2. 1.2. 编写服务
      1. 1.2.1. 首先编写服务的接口,其有一个sayHi方法向提交姓名者输出“Hello”
      2. 1.2.2. 然后写实现类
      3. 1.2.3. 声明服务beans | Declaring your server beans
      4. 1.2.4. 设置Servlet环境 | Setting up the Servlet
    3. 1.3. 创建客户端(简便方法) | Create a Client (Easy Way)
    4. 1.4. 创建客户端(更复杂方法)| Create a Client (More Manual Way)
    5. 1.5. 进一步操作 | Advanced Steps
|