Webservice實踐(五)基於CXF的服務端開發
本節將實踐目前最流行的第二種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(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
點選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的。