参考官网文档:http://cxf.apache.org/docs/writing-a-service-with-spring.html
从官网上下载 cxf 的包,包里会有 samples 文件夹,该文件夹中存放的就是cxf 的一些小例子
这里就是针对 java_first_spring_support 例子的改写 与 说明,该例子是采用 spring +maven +cxf 技术
创建项目
- 使用Eclipse 创建一个 Maven Project,工程名为 TestCXFDome1 ,修改pom.xml 引入需要使用的jar 包
<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>panie</groupId> <artifactId>TestCXFDome1</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>TestCXFDome1 Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <cxf.version>3.1.6</cxf.version> <springframework.version>4.1.9.RELEASE</springframework.version> </properties> <dependencies> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>3.1.6</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> <version>3.1.6</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> <type>jar</type> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> <type>jar</type> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.1</version> <scope>provided</scope> </dependency> </dependencies> <build> <finalName>TestCXFDome1</finalName> </build> </project>
编写服务端
- 首先写一个接口。@WebService注解表示是要发布的web服务
package demo.spring.service; import javax.jws.WebService; @WebService public interface HelloWorld { String sayHi(String text); }
- 对该接口写一个实现类。@WebService注解表示是要发布的web服务,endpointInterface参数的值是该服务类对应的接口。
package demo.spring.service; import javax.jws.WebService; @WebService(endpointInterface = "demo.spring.service.HelloWorld") public class HelloWorldImpl implements HelloWorld { public String sayHi(String text) { System.out.println("sayHi called"); return "Hello " + text; } }
- 声明 server bean
CXF 支持 Spring 2.0 Schema 标签配置方式,并且提供快捷暴露 Web Services 的标签。对于 JAX_WS 端,我们可以使用<jaxws:endpoint> 来设置服务器端的 endpoint (请参考英文原文)
1)我们需要引入 Spring 与 CXF 的命名空间(namespace),这样,我们可以使用 Spring 与 CXF 的标签配置了。 2)我们需要引入我们所需要的 CXF 的 Bean 定义文件
3)定义我们具体实现的 Bean
在 WEB-INF 目录下创建一个 cxf-servlet.xml 文件来声明 一个endpoint bean
<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" />
id - 指在 spring context 中的bean id
implementor - 指定 实现类。当使用bean 来表示实现类时,使用 #bean-name
address - 指 服务将会被发布的位置,这里只能使用相对路径。因为CXF 不知道 war 名字,也不知道 容器端口,CXF 运行时将会更新 endpoint 地址
- 配置Servlet
如果采用 默认路径的 cxf-servlet.xml ,在web.xml 中配置
<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>/*</url-pattern> </servlet-mapping>
如果 cxf-servlet.xml 更换的位置 或者 名字,如改为 beans.xml ,则需要在 web.xml 中配置
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:/beans.xml</param-value> </context-param> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener>
部署到web服务器上,发布webservice工程,输入http://localhost:8080/TestCXFDome1/HelloWorld?wsdl
编写客户端(一)
在客户端可以使用 <jaxws:client> 来声明。你只需要提供 bean name,服务接口,服务请求URL,它就可以在远程SOAP服务器上创建一个指定名称的bean来实现服务接口。
- 配置一个 client-bean.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/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:8080/TestCXFDome1/HelloWorld"/> </bean> </beans>
- 编写一个 测试类 Client
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 } }
运行 测试类,即可看到 调用 服务的结果
编写客户端(二)
package demo.spring.client; import org.apache.cxf.jaxws.JaxWsProxyFactoryBean; import demo.spring.service.HelloWorld; public class Client2 { public static void main(String[] args) { //创建WebService客户端代理工厂 JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); //注册WebService接口 factory.setServiceClass(HelloWorld.class); //设置WebService地址 factory.setAddress("http://localhost:8180/TestCXFDome1/HelloWorld"); HelloWorld hello = (HelloWorld)factory.create(); //调用webservice接口方法 String response = hello.sayHi("panie");//返回sucess System.out.println("Response: " + response); } }