官网下载地址:http://cxf.apache.org/download.html
我下载的是最新版本:apache-cxf-2.7.8 IDE:springsource jdk:jdk1.7.0_17
webservice服务端创建
1、新建一个maven项目
由于我使用的IED是springsource,支持maven。所以新建项目就创建了一个maven项目,这样cxf的依赖包就不用手动导入,直接在pom文件中配置依赖即可。cxf的maven
的依赖配置可以上cxf官网的User Guide中查找,http://cxf.apache.org/docs/using-cxf-with-maven.html#UsingCXFwithmaven-MavenPlugin这个章节有maven依赖的说明。
若新建的项目不为maven项目,也可以将下载下来的cxf包中的apache-cxf-2.7.8\lib目录下的jar包导入到项目中。
添加完cxf依赖的pom文件如下:
cxf-rt-transports-http-jetty这个jar包现在需要配置上,若创建的项目为web项目,最终要部署到web服务器上,这个依赖可以不配置。
<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>cxf</groupId>
<artifactId>server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>server</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<cxf.version>2.7.8</cxf.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>${cxf.version}</version>
</dependency>
<!-- Jetty is needed if you're are not using the CXFServlet -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>${cxf.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
2、编写需要发布的服务接口
新建一个实体类User
package com.service.entity;
public class User
{
private String firstName;
private String secondName;
//此处省略getters and setters
@Override
public String toString() {
return firstName + " " + secondName;
}
}
新建一个接口,注意其中的注解。WebResult和WebParam注解是指定参数在Soap报文中的名称,需要在接口中指定
package com.service;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import com.service.entity.User;
@WebService
public interface HelloService
{
public @WebResult(name="greet") String sayHello(@WebParam(name="user") User user);
}
新建接口的实现类,实现类中需要用WebService注解指定其实现的接口
package com.service.impl;
import javax.jws.WebService;
import com.service.HelloService;
import com.service.entity.User;
@WebService(endpointInterface="com.service.HelloService")
public class HelloServiceImpl implements HelloService
{
@Override
public String sayHello(User user)
{
return "hello, " + user;
}
}
3、发布服务
package com.service.start;
import javax.xml.ws.Endpoint;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
import com.service.HelloService;
import com.service.impl.HelloServiceImpl;
public class Server
{
public static void main(String[] args)
{
//JAX-WS的发布方式
//Endpoint.publish("http://127.0.0.1:8888/cxf_hello", new HelloServiceImpl());
//CXF的发布方式
HelloServiceImpl hello = new HelloServiceImpl();
JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
//接口
factory.setServiceClass(HelloService.class);
//实现类 此处是一个实例
factory.setServiceBean(hello);
//发布地址
factory.setAddress("http://127.0.0.1:8888/cxf_hello");
//打印日志
factory.getInInterceptors().add(new LoggingInInterceptor());
factory.getOutInterceptors().add(new LoggingOutInterceptor());
factory.create();
}
}
注意factory.setServiceBean方法参数是实现类的一个实例,不可是HelloServiceImpl.class
可参考官网中服务发布及client访问的实现方式:http://cxf.apache.org/docs/a-simple-jax-ws-service.html
运行Server的main方法,服务就可以发布成功
4、验证
1、在浏览器中输入http://127.0.0.1:8888/cxf_hello?wsdl地址,能显示WSDL文件信息,表示服务发布成功
2、也可以使用soupUI访问接口查看结果是否正确
将步骤1中浏览器显示的信息保存为hello.wsdl文件,导入到soupUI中,访问接口sayHello,看返回的soap报文中的信息是否与接口中的返回值一致
注意请求报文中节点名称user和返回报文中节点名称greet,这些别名都是我们在接口中使用注解指定的
3、最后一种验证方式自然就是新建客户端代码访问服务
新建客户端maven项目:pom文件与服务端项目的pom文件大致相似。需要将artifactId修改为client;cxf-rt-transports-http-jetty依赖也可以不配置。
手动执行wsdl2java命令:在控制台cmd下,进入到apache-cxf-2.7.8\bin目录下(也可以将cxf的bin目录添加到系统环境变量的path路径中,这样就不用cd到cxf 的bin目录下就可以执行wsdl2java命令),执行命令: wsdl2java -d D:/ -keep http://127.0.0.1:8888/cxf_hello
wsdl2java命令执行完可生成客户端代码,-d参数指定生成的代码存放的目录,本例中放到D盘的跟目录;最后http://127.0.0.1:8888/cxf_hello这个地址是webservice的服务地址
到D盘跟目录下找到生成的代码,复制到新建的客户端项目中
wsdl2java命令和jdk提供的wsimport命令的功能类似
由于新建的是maven项目,此处wsdl2java也可以直接通过maven插件实现
编写client类
package com.service.client;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import com.service.HelloService;
import com.service.User;
public class Client
{
public static void main(String[] args)
{
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
//接口
factory.setServiceClass(HelloService.class);
//发布地址
factory.setAddress("http://127.0.0.1:8888/cxf_hello");
//打印日志
factory.getInInterceptors().add(new LoggingInInterceptor());
factory.getOutInterceptors().add(new LoggingOutInterceptor());
HelloService serice = (HelloService)factory.create();
User user = new User();
user.setFirstName("zhang");
user.setSecondName("san");
String greet = serice.sayHello(user);
System.out.println(greet);
}
}
client的代码和服务端发布的代码大致一致,只不过工厂使用的是代理工厂
运行client代码,控制台打印出:hello, zhang san ,访问服务成功
客户端代码Client类中使用到的HelloService,User等类,都是通过wsdl2java生成的