本節将實踐目前最流行的第二種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) ;
}
StudentWsImpl.java源碼如下:
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(endpointInter,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
點選wsdl連結可以看到接口說明wsdl文檔
好了,簡單的服務端就寫到這裡。(注: 實質上這裡是利用java ws 釋出服務端)
四、CXF 用戶端編寫
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的。