本节将实践目前最流行的第二种web service 发布和调试框架 CXF
Apache CXF 是一个开放源代码框架,提供了用于方便地构建和开发 Web 服务的可靠基础架构。它允许创建高性能和可扩展的服务,您可以将这样的服务部署在 Tomcat 和基于 Spring 的轻量级容器中,以及部署在更高级的服务器上。Java的webService实现本身就是一个很耗性能的实现方案(xml与java对象之间在服务端以及客户端的互转比较消耗性能),目前java主流的webService应用以CXF、AXIS2为主,CXF比AXIS2效率更高,并且在java 应用中CXF很成熟,因此CXF在webservice中占有非常重要的地位。
下面一张网络上的图比较好的说明了CXF 与web service的关系
下面将具体说说如何使用CXF 进行Webservice 开发。关于CXF的实践分2篇,第一篇通过注解发布webservice,利用cxf 进行客户端开发。 第二篇:通过spring与cxf 结合进行发布
1、 webservice 发布服务
2、使用CXF 进行 客户端开发
1、 myeclipse
2、cxf 包
1、首先在myeclipse中创建一个java web project
工程里面的实体类、DAO类就沿用上一篇中的类。 它们是Student.java StudentDAO.java StudentDAOImpl.java StudentSimlationDB.java.
这里重点贴一下 StudentWs.java 和 StudentWsImpl.java. StudentWs是暴露的接口类,也是web service 服务接口, 实现类是服务的实现。
整个工程的结构如下图:
下面列出 StudentWs.java 和 StudentWsImpl.java这两个类的源码,其他类源码见其他
StudentWs.java源码如下:
package com.study.cxfws;
import javax.jws.WebParam;
import javax.jws.WebService;
//这个接口是用来暴露给外部的webservice类
//只提供接口是为了服务端便于扩展,增加灵活性
@WebService
public interface StudentWs {
//暴露的接口 增加学生
public boolean addStudent(@WebParam(name="name")String name, @WebParam(name="sex")String sex, @WebParam(name="birthday")String birthday);
//暴露的接口查询学生
public String queryStudent(@WebParam(name="studentName")String studentName) ;
}
package com.study.cxfws.impl;
import com.study.cxfws.StudentWs;
import com.study.dao.StudentDAO;
import com.study.dao.impl.StudentDAOImpl;
import javax.jws.WebService;
import javax.xml.ws.Endpoint;
@WebService(endpointInterface="com.study.cxfws.StudentWs",serviceName="StudentWs")
public class StudentWsImpl implements StudentWs {
//Student的dao 类,负责处理student 实体类的操作
private StudentDAO studentDAO;
public StudentWsImpl(){
studentDAO = new StudentDAOImpl();
}
public boolean addStudent(String name, String sex, String birthday) {
// 调用studentDAO.addStudent 方法入库
System.out.println("Now put student into DB!");
studentDAO.addStudent(name, sex, birthday);
return true;
}
public String queryStudent(String studentName) {
System.out.println("StudentWsImpl queryStudent->"+studentName);
Object tmp = studentDAO.queryStudent(studentName);
if (tmp== null) {
return "null";
} else {
return tmp.toString();
}
}
public static void main(String[] args) {
System.out.println("web service start");
StudentWsImpl studentWs= new StudentWsImpl();
String address="http://localhost:8080/StudentWs?wsdl";
Endpoint.publish(address, studentWs);
System.out.println("web service started");
}
}
在整个工程上,选中 StudentWsImpl.java 右键运行,url:http://localhost:8080/StudentWs
好了,简单的服务端就写到这里。(注: 实质上这里是利用java ws 发布服务端)
1、下载cxf工具
可以从下面URL下载cxf, http://cxf.apache.org/download.html, 将下载的apache-cxf-3.1.10.zip 保存到本地,并解压。
2、利用cxf的工具 wsdl2java 将 服务端发布的wsdl 进行编译转换为java
这些是使用cxf 里面的工具wsdl2java 生成的java类。在命令行执行下面命令,就可以生成这些类
E:\cwqwork\myeclipse_workspace\StudyWSCxfStudentCli\src>F:\lib\cxf\apache-cxf-3.1.10\bin\wsdl2java http://localhost:8080/StudentWs?wsdl
3、编写client端类
package com.study.cxfws.client;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import com.study.cxfws.StudentWs;
public class StudentWsClient {
/**
* @param args
*/
public static void main(String[] args) {
//首先右键run as 运行com.hsy.server.webServiceApp类,然后再运行这段客户端代码
JaxWsProxyFactoryBean jwpfb = new JaxWsProxyFactoryBean();
jwpfb.setServiceClass(StudentWs.class);
jwpfb.setAddress("http://localhost:8080/StudentWs");
StudentWs ws = (StudentWs) jwpfb.create();
ws.addStudent("Tom", "male", "19780618");
ws.addStudent("Jerry", "female", "19800323");
System.out.println( ws.queryStudent("Tom") );
System.out.println( ws.queryStudent("Jerry") );
}
}
4、为客户端加上cxf需要的jar包,否则运行会报错误
5、在StudentWsClient.java 右键run as -》java application
执行结果如下:
五、服务端修改发布方式:用cxf 框架 替换 javax ws 方式
前面的服务端,我们可以看到是采用 java ws方式,也就是说并没有用到cxf框架,下面说明一下如何用cxf 发布。
1、修改服务端 StudentWsImpl.java
源码如下:
package com.study.cxfws.impl;
import javax.jws.WebService;
import com.study.cxfws.StudentWs;
import com.study.dao.StudentDAO;
import com.study.dao.impl.StudentDAOImpl;
import org.apache.cxf.endpoint.Server;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
@WebService
public class StudentWsImpl implements StudentWs {
//Student的dao 类,负责处理student 实体类的操作
private StudentDAO studentDAO;
public StudentWsImpl(){
studentDAO = new StudentDAOImpl();
}
public boolean addStudent(String name, String sex, String birthday) {
// 调用studentDAO.addStudent 方法入库
System.out.println("Now put student into DB!");
studentDAO.addStudent(name, sex, birthday);
return true;
}
public String queryStudent(String studentName) {
System.out.println("StudentWsImpl queryStudent->"+studentName);
Object tmp = studentDAO.queryStudent(studentName);
if (tmp== null) {
return "null";
} else {
return tmp.toString();
}
}
public static void main(String[] args) {
System.out.println("web service start");
JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
//这里必须传入class,不能是接口,否则客户端会报异常 Could not instantiate service class ... because it is an interface
factory.setServiceClass(StudentWsImpl.class);
factory.setAddress("http://localhost:8080/StudentWs");
Server server = factory.create();
server.start();
System.out.println("web service started");
}
}
2、服务端通过run as 运行起来后,重新执行wsdl2java 命令,生成客户端需要的java
3、在StudentWsClient.java 上运行客户端,得到的效果与前面一致。说明用CXF发布服务端也是OK的。