webservice(三) 使用JDK的EndPoint和cxf框架分別釋出webservice服務
JAX-WS是指Java Api for XML – WebService.
與web服務相關的是EndPoint類,此類為端點服務類,它提供一個publish方法用於將一個已經添加了@WebService註解物件繫結到一個地址的埠上。
使用jdk的EndPoint釋出web服務
1.在要釋出服務的類上新增@WebService註解。將要釋出服務的方法設定為public。2.呼叫EndPoint.publish(,)釋出服務
其他注意事項:
1.給類新增上@WebService註解後,類中所有的非靜態方法都將會對外公佈。
2.不支援靜態方法,final方法。
3.如果希望某個方法(非static,非final)不對外公開,可以在方法上新增@WebMethod(exclude=true),阻止對外公開。
4.被添加了@WebService註解的類至少要有一個可以公開的方法,否則將會啟動失敗。
使用CXF框架釋出服務
釋出服務
兩種方式釋出服務:ServerFactoryBean 和JaxWsServerFactoryBean
JaxWsServerFactoryBean是ServerFactoryBean 的子類,也是功能擴充套件類。
1.ServerFactoryBean 方式
public class ServerFactoryBeanDemo { public String sayHi(String name){ String s="hello "+name; return s; } public static void main(String[] args) { ServerFactoryBean sf=new ServerFactoryBean(); //服務實現類 sf.setServiceClass(ServerFactoryBeanDemo.class); //服務的釋出地址 sf.setAddress("http://localhost:5678/hello"); //服務的例項 sf.setServiceBean(new ServerFactoryBeanDemo()); //釋出服務 sf.create(); System.out.println("server ready……"); } }
ServerFactoryBean 方式
①不需要提供@WebService註解,依舊可以釋出
②不需要提供對外暴露的方法,依舊可以釋出(當然這也沒什麼意義)
2.JaxWsServerFactoryBean方式(建議使用)
@WebService public class JaxWsServiceDemo { public String sayHi(String name) { String s = "hello " + name; return s; } public static void main(String[] args) { JaxWsServerFactoryBean sf = new JaxWsServerFactoryBean(); // 服務實現類 sf.setServiceClass(JaxWsServiceDemo.class); // 服務的釋出地址 sf.setAddress("http://localhost:5678/hello"); // 服務的例項 sf.setServiceBean(new JaxWsServiceDemo()); // 釋出服務 sf.create(); System.out.println("server ready……"); } }
JaxWsServerFactoryBean方式
①需要提供@WebService註解
雖然不提供該註解也可以釋出成功,但是暴露的方法依舊無法顯示,所以通常也會提供註解來顯示暴露的方法。
(可以通過檢視wsdl文件來驗證)
標準的做法
通常會提供一個服務介面,用以表明服務的型別。要加上@Webservice註解。這有點類似於Spring中的服務層的實現。
注意:不提供介面也行,但是在任何情況下都建議使用介面。
如果使用spring的配置檔案釋出,則必須提供介面。
@WebService
public interface IHelloService {
public String sayHi(String name);
}
然後提供一個實現類
public class HelloServiceImpl implements IHelloService{
@Override
public String sayHi(String name) {
String s = "hello " + name;
return s;
}
public static void main(String[] args) {
JaxWsServerFactoryBean sf = new JaxWsServerFactoryBean();
// 服務的型別
sf.setServiceClass(IHelloService.class);//注意:介面型別
// 服務的釋出地址
sf.setAddress("http://localhost:5678/hello");
// 服務的實現類例項
sf.setServiceBean(new HelloServiceImpl());//注意:實現類例項
// 釋出服務
sf.create();
System.out.println("server ready……");
}
}
wsdl2java工具
cxf也提供了一個用於生成客戶端呼叫程式碼的工具wsdl2java.exe。它的功能同wsimport一樣。它是可以支援SOAP1.1 和SOAP1.2的協議的。
此工具位於cxf_home/bin目錄下。引數與wsimport有所不同。
它包含以下引數:
-d引數,指定程式碼生成的目錄。
-p引數,指定生成的新的包結構。
注意:由於wsdl2java是根據jdk1.7生成的原生代碼,所以,需要對生成的程式碼做一點點修改。
在jdk1.6中的javax.xml.ws.Service的構造方法接收二個引數為:(String url,QName qname);
在jdk1.7中的javax.xml.ws.Service的構造方法中接收三個引數為:(String url,QName qname,features);
2、將生成的程式碼,拷貝到專案目錄,然後使用以前相同方法呼叫。
注意:如果將@WebMethod設定了header=true引數,將會在呼叫時多傳遞一個引數。引數可以直接傳null值。
對於這種情況,可以將header=true修改成header=false然後再重要獲取客戶端原始碼。
3、可能發現,使用cxf生成的客戶端程式碼與wsimport差不多,甚至是一樣,那為什麼還要使用cxf呢?
原因:它較好的釋出方式、較容易的與其他伺服器整合、及與Spring的完美結合都不得不讓我們使用cxf。
對於上面標準實現中的程式碼執行該命令,會生成程式碼供客戶端使用。(用法類似於wsimport)
給服務新增訊息攔截器
作用:類似於使用TCP/IP Monitor,用來捕獲SOAP訊息的過程。
LoggingInInterceptor – 資訊輸入時的攔截器 –請求
LoggingOutInterceptor –資訊輸出時的攔截器 - 響應
server.getInInterceptors().add(new LoggingInInterceptor());
server.getOutInterceptors().add(new LoggingOutInterceptor());
public class Server {
public static void main(String[] args) {
JaxWsServerFactoryBean sf = new JaxWsServerFactoryBean();
sf.setServiceClass(IHelloService.class);
sf.setServiceBean(new HelloServiceImpl());
sf.setAddress("http://localhost:5678/hello");
// 加入請求的訊息攔截器
sf.getInInterceptors().add(new LoggingInInterceptor());
// 加入響應的訊息攔截器
sf.getOutInterceptors().add(new LoggingOutInterceptor());
sf.create();
System.out.println("server ready……");
}
}
可以在服務端控制檯檢視 攔截到的請求資訊和傳送給客戶端的響應資訊。