WebService從來都很受重視,特別是Java陣營,WebService框架和技術層出不窮。知名的XFile(新的如CXF)、Axis一、Axis2等。html
而Sun公司也不甘落後,從早期的JAX-RPC到如今成熟的、支持RPC調用與消息傳遞的JAX-WS都通過了市場的考驗,十分紅熟,並且使用JAX-WS開發WebService的收益是很大的,它是輕量級的。java
咱們使用JAX-WS開發WebService只須要很簡單的幾個步驟:寫接口和實現=>發佈=>生成客戶端(測試或使用)。web
而在開發階段咱們也不須要導入外部jar包,由於這些api都是現成的。首先是接口的編寫(接口中只須要把類註明爲@WebService,把要暴露給客戶端的方法註明爲@WebMethod便可,其他如@WebResult、@WebParam等都不是必要的,而客戶端和服務端的通訊用RPC和Message-Oriented兩種,區別和配置之後再說):sql
1 package service; 2 3 import java.util.Date; 4 5 import javax.jws.WebMethod; 6 import javax.jws.WebParam; 7 import javax.jws.WebResult; 8 import javax.jws.WebService; 9 import javax.jws.soap.SOAPBinding; 10 11 /** 12 * 做爲測試的WebService接口 13 * 14 * @author Johness 15 * 16 */ 17 @WebService 18 @SOAPBinding(style = SOAPBinding.Style.RPC) 19 public interface SayHiService { 20 21 /** 22 * 執行測試的WebService方法 23 */ 24 @WebMethod 25 void SayHiDefault(); 26 27 /** 28 * 執行測試的WebService方法(有參) 29 * 30 * @param name 31 */ 32 @WebMethod 33 void SayHi(@WebParam(name = "name") String name); 34 35 /** 36 * 執行測試的WebService方法(用於時間校驗) 37 * 38 * @param clentTime 客戶端時間 39 * @return 0表示時間校驗失敗 1表示校驗成功 40 */ 41 @WebMethod 42 @WebResult(name = "valid") 43 int CheckTime(@WebParam(name = "clientTime") Date clientTime); 44 }
而後是實現類(註解@WebService及其endpointInterface屬性是必要的):api
1 package service.imp; 2 3 import java.text.SimpleDateFormat; 4 import java.util.Date; 5 6 import javax.jws.WebService; 7 import javax.jws.soap.SOAPBinding; 8 9 import service.SayHiService; 10 11 /** 12 * 做爲測試的WebService實現類 13 * 14 * @author Johness 15 * 16 */ 17 @WebService(endpointInterface = "service.SayHiService") 18 @SOAPBinding(style = SOAPBinding.Style.RPC) 19 public class SayHiServiceImp implements SayHiService { 20 21 @Override 22 public void SayHiDefault() { 23 System.out.println("Hi, Johness!"); 24 } 25 26 @Override 27 public void SayHi(String name) { 28 System.out.println("Hi, " + name + "!"); 29 } 30 31 @Override 32 public int CheckTime(Date clientTime) { 33 // 精確到秒 34 String dateServer = new java.sql.Date(System.currentTimeMillis()) 35 .toString() 36 + " " 37 + new java.sql.Time(System.currentTimeMillis()); 38 String dateClient = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") 39 .format(clientTime); 40 return dateServer.equals(dateClient) ? 1 : 0; 41 } 42 43 }
而後是發佈(通常有兩種方式):瀏覽器
方式一(此方式只能做爲調試,有如下bug:服務器
jdk1.6u17?如下編譯器不支持以Endpoint.publish方式發佈document方式的soap,必須在service接口和實現類添加「@SOAPBinding(style = SOAPBinding.Style.RPC)」註解;app
訪問受限,彷佛只能本機訪問(應該會綁定到publish的URL上,以下使用localhost的話就只能本機訪問)……):框架
1 package mian; 2 3 import javax.xml.ws.Endpoint; 4 5 import service.imp.SayHiServiceImp; 6 7 public class Main { 8 9 /** 10 * 發佈WebService 11 * 簡單 12 */ 13 public static void main(String[] args) { 14 Endpoint.publish("http://localhost:8080/testjws/service/sayHi", new SayHiServiceImp()); 15 } 16 17 }
方式二(基於web服務器Servlet方式):jsp
以Tomcat爲例,首先編寫sun-jaxws.xml文件並放到WEB-INF下:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" 3 version="2.0"> 4 <endpoint name="SayHiService" 5 implementation="service.imp.SayHiServiceImpl" 6 url-pattern="/service/sayHi" /> 7 </endpoints>
而後改動web.xml,添加listener和servlet(url-pattern要相同哦):
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> 3 4 <listener> 5 <listener-class> 6 com.sun.xml.ws.transport.http.servlet.WSServletContextListener 7 </listener-class> 8 </listener> 9 <servlet> 10 <servlet-name>SayHiService</servlet-name> 11 <servlet-class> 12 com.sun.xml.ws.transport.http.servlet.WSServlet 13 </servlet-class> 14 </servlet> 15 <servlet-mapping> 16 <servlet-name>SayHiService</servlet-name> 17 <url-pattern>/service/sayHi</url-pattern> 18 </servlet-mapping> 19 20 <welcome-file-list> 21 <welcome-file>index.html</welcome-file> 22 <welcome-file>index.htm</welcome-file> 23 <welcome-file>index.jsp</welcome-file> 24 </welcome-file-list> 25 </web-app>
最後部署到Tomcat裏,值得一提的是您可能須要添加如下jar包(由於Tomcat沒有):
啓動Tomcat。
服務端工做就完成了,注意兩個事情。
注意:項目須要使用UTF-8編碼(至少sun-jaxws.xml必須是UTF-8格式的);
對於MyEclipse的內置Tomcat,可能會出現不須要手動添加上述jar包,但獨立部署時應該添加,由於它們使用的class-path不同;
多個不一樣路徑的接口也要使用同一個WSServlet;
最好加上@SOAPBinding(style = SOAPBinding.Style.RPC)註解。
部署好了以後打開瀏覽器輸入網址:http://localhost:8080/testjws/service/sayHi?wsdl。能夠看到東西就證實發布成功了。
附上項目樹狀圖:
最後是客戶端使用,因爲WebService是平臺和語言無關的基於xml的,因此咱們徹底可使用不一樣語言來編寫或生成客戶端。
通常有三種方式來使用(對於Java語言而言):
一,使用jdk自帶工具wsimport生成客戶端:
jdk自帶的wsimport工具生成,上圖我是把客戶端文件生成到了桌面src文件中(-d),並保留了源文件(-keep),指定了包名(-p)。
而後咱們就可使用生成的文件來調用服務器暴露的方法了:
值得一提的是你生成使用的jdk和你客戶端的jre須要配套!
從上面的目錄結構咱們能夠發現:服務端的每一個webmethod都被單獨解析成爲了一個類(若是使用了實體,實體也會被解析到客戶端,而且是源碼,因此建議使用實體時慎重)。
(上面的圖是舊圖,只是爲了表示一下jaxws是爲每一個webmethod生成類的狀況)
而咱們的service則被生成了一個代理類來調用服務,接下來咱們看看使用狀況:
1 package test; 2 3 import java.util.Date; 4 import java.util.GregorianCalendar; 5 6 import javax.xml.datatype.DatatypeConfigurationException; 7 import javax.xml.datatype.DatatypeFactory; 8 import javax.xml.datatype.XMLGregorianCalendar; 9 10 import testjws.client.SayHiService; 11 import testjws.client.SayHiServiceImpService; 12 13 public class Main { 14 15 public static void main(String[] args) throws DatatypeConfigurationException { 16 // 獲取service 17 SayHiService service = new SayHiServiceImpService().getSayHiServiceImpPort(); 18 19 // sayhi 20 service.sayHiDefault(); 21 service.sayHi("Ahe"); 22 23 // checktime 24 // 這裏主要說一下時間日期的xml傳遞,方法還略顯複雜 25 GregorianCalendar calender = new GregorianCalendar(); 26 calender.setTime(new Date(System.currentTimeMillis())); 27 XMLGregorianCalendar xmldate = DatatypeFactory.newInstance().newXMLGregorianCalendar(calender); 28 System.out.println(service.checkTime(xmldate)); 29 30 } 31 32 }
看看服務器的輸出,咱們是否調用成功:
成功了!
對於校驗時間的方法客戶端也收到反饋了:
二,使用諸如MyEclipse(Eclipse for Jave EE也能夠)建立一個Web Service Client的項目
而後填入wsdl地址便可,後續步驟我就不貼出了。
三,本身寫代碼-_-,其實這個方法不得不說是最好的。
(最後編輯時間2014-03-08 00:23:18)