實戰CXF呼叫Webxml天氣預報服務
[url]http://my.oschina.net/bayer/blog/52490[/url]
實戰CXF呼叫Webxml天氣預報服務
今晚群裡的kasasis同學問我會不會使用CXF呼叫
[url]http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl[/url]
這個天氣預報的WebService服務;
我也是初學者, 在嘗試呼叫的過程中發現不少問題, 也有一些小心得, 希望與大家分享, 更希望大家可以幫我解惑.
[color=red][b]一.初探:通過wsdl2java生成呼叫遠端服務所需要的java類[/b][/color]
因為還沒有成功使用dynamic-clients(http://cxf.apache.org/docs/dynamic-clients.html)的方式動態呼叫過WebService服務, 所以決定使用CXF提供的wsdl2java來生成呼叫WebService服務所必須的java類, 進而使用JaxWsServerFactoryBean來呼叫WebService服務:
[img]http://static.oschina.net/uploads/space/2012/0406/005536_rxYD_184760.png[/img]
遺憾的是, CXF wsdl2java報錯了:
[i]undefined element declaration 's:schema'
at line 85 column 41 of schema [/i]
[url]http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl[/url]
將該wsdl下載下來, 使用MyEclipse 9.0開啟並檢視, 也提示了這一錯誤:
src-resolve.4.2: Error resolving component 's:schema'.
It was detected that 's:schema' is in namespace 'http://www.w3.org/2001/XMLSchema', but components from this namespace are not referenceable from schema document 'file:///D:/workspace/workspace_j2ee/CXFWeatherTest/src/WeatherWebService.asmx.original.wsdl'.
If this is the incorrect namespace, perhaps the prefix of 's:schema' needs to be changed.
If this is the correct namespace, then an appropriate 'import' tag should be added to 'file:///D:/workspace/workspace_j2ee/CXFWeatherTest/src/WeatherWebService.asmx.original.wsdl'.
wsdl報錯部分內容如下(下邊程式碼紅色部分):
作為初學者, 曾在風中葉老師的視訊中學習過關於schema及DTD的一些知識, 但還沒修煉到能解決這一錯誤的程度, 也期待各位同學的積極探索並給出答案;
問題催人奮進, 折衷的辦法總是有的:
<s:any/>既然可以代表任何元素, 為什麼不能代表<s:element ref="xxx"/>元素呢? 於是乎, 憤然刪除<s:element ref="s:schema" />, 勉強算是通過了CXF提供的wsdl驗證工具wsdlvalidator的驗證;
Ok, 繼續之前的步驟, 通過wsdl2java來生成呼叫遠端WebService服務所需要的java類;
一切順利, 生成的類的目錄結構如下:
[img]http://static.oschina.net/uploads/space/2012/0406/005423_iXEa_184760.png[/img]
[color=red][b]二.使用JaxWsProxyFactoryBean呼叫天氣服務[/b][/color]
本工程使用的jar包如下圖示:
[img]http://static.oschina.net/uploads/space/2012/0406/005630_GAWN_184760.png[/img]
通過JaxWsProxyFactoryBean呼叫webService服務的過程相信大家都很熟悉了, 具體程式碼如下:
執行還算順利, 得到的結果如下:
資訊: Outbound Message
---------------------------
[color=darkblue]ID: 1
Address: http://www.webxml.com.cn/WebServices/WeatherWebService.asmx
Encoding: UTF-8
Content-Type: text/xml
Headers: {Accept=[*/*], SOAPAction=["http://WebXml.com.cn/getWeatherbyCityName"]}
Payload:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<getWeatherbyCityName xmlns="http://WebXml.com.cn/">
<theCityName>南陽</theCityName>
</getWeatherbyCityName>
</soap:Body>
</soap:Envelope>
河南
南陽
57178
57178.jpg
2012-4-5 22:58:11
11℃/24℃
4月6日 晴
無持續風向微風
0.gif
0.gif
今日天氣實況:氣溫:16℃;風向/風力:北風 0級;溼度:53%;空氣質量:較差;紫外線強度:中等
穿衣指數:建議著薄型套裝等春秋過渡裝。年老體弱者宜著套裝。但晝夜溫差較大,注意適當增減衣服。
感冒指數:晝夜溫差較大,較易發生感冒,請適當增減衣服。體質較弱的朋友請注意防護。
運動指數:天氣較好,趕快投身大自然參與戶外運動,盡情感受運動的快樂吧。
洗車指數:適宜洗車,未來持續兩天無雨天氣較好,適合擦洗汽車,藍天白雲、風和日麗將伴您的車子連日潔淨。
晾曬指數:天氣不錯,適宜晾曬。趕緊把久未見陽光的衣物搬出來吸收一下太陽的味道吧!
旅遊指數:天氣晴朗,風和日麗,溫度適宜,是個好天氣哦。這樣的天氣很適宜旅遊,您可以盡情地享受大自然的風光。
路況指數:天氣較好,路面比較乾燥,路況較好。
舒適度指數:溫度適宜,風力不大,您在這樣的天氣條件下,會感到比較清爽和舒適。
空氣汙染指數:氣象條件較不利於空氣汙染物稀釋、擴散和清除,請適當減少室外活動時間。
紫外線指數:屬中等強度紫外線輻射天氣,外出時建議塗擦SPF高於15、PA+的防曬護膚品,戴帽子、太陽鏡。
11℃/24℃
4月7日 晴
無持續風向微風
0.gif
0.gif
10℃/23℃
4月8日 陰轉多雲
無持續風向微風
2.gif
1.gif
南陽市位於河南省西南部,北靠伏牛山,東扶桐柏山,西依秦嶺,南臨漢江。..................[/color]
[color=red][b]三.使用JaxWsDynamicClientFactory呼叫天氣服務[/b][/color]
CXF關於Dynamic-clients的介紹文件見:
[url]http://cxf.apache.org/docs/dynamic-clients.html[/url]
很簡潔的一段官方示例程式碼:
但具體的呼叫過程並非一帆風順; 讓人不解的是, 即使呼叫自己所建立的WebService, 使用動態方式呼叫也不能成功, 總會提示一個異常:
Exception in thread "main" java.lang.IllegalStateException: Unable to write generated Java files for schemas: null
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:351)
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:234)
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:227)
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:182)
at com.client.Test.dynamicStudent(Test.java:30)
at com.client.Test.main(Test.java:38)
Caused by: java.lang.reflect.UndeclaredThrowableException
at $Proxy29.build(Unknown Source)
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:349)
... 5 more
Caused by: java.lang.NoSuchMethodException:
com.sun.codemodel.internal.JCodeModel.build(java.lang.Object)
at java.lang.Class.getMethod(Class.java:1605)
at org.apache.cxf.common.util.ReflectionInvokationHandler.invoke(ReflectionInvokationHandler.java:50)
... 7 more
異常資訊的最後一個Caused by給了我線索:
java.lang.NoSuchMethodException:
com.sun.codemodel.internal.JCodeModel.build(java.lang.Object)
遍歷工程所用jar檔案, 居然沒有找到internal包下的類JCodeModel;
但報的異常是NoSuchMethodException, 而不是ClassNotFoundException, 表明該類是存在的, 可能包路徑發生了變化, 遂STFG(search the fUcking google. 從陳皓老師的博文學到的 - - 囧), 最終發現該類現存在於jaxb-xjc-2.2.4-1.jar中, 包路徑為com.sun.codemodel, 而不是異常中所提示的com.sun.codemodel.internal;
為什麼會這樣? 難道是我的jaxb-xjc jar包的版本不對?
遂通過http://jaxb.java.net/, 對比jaxb2.0.1 -- 2.2.5之間的所有版本, 均沒有找到包com.sun.codemodel.internal...
Ok, 讓我們繼續查詢jaxb1.x版本的jar包;
幸運的是, 在頁面[url]http://jaxb.java.net/nonav/2.0.1/docs/jaxb-1_0.html [/url], 終於有所發現:
JAXB 2.0 is backwards compatible with JAXB 1.0 - you can deploy your existing 1.0 applications on the 2.0 runtime (provided that you also bundle the jaxb1-impl.jar) and they should run without modification.
檢視我的專案的類庫, 剛好缺少了這麼一個jaxb-impl.jar包,,, 加上該包(我使用的是jaxb-impl-2.2.4-1.jar), 再次執行動態呼叫天氣預報WebService的服務, Congratulations! 這個異常被幹掉了!
但是, 不要高興的太早, 服務並沒有呼叫成功, 因為又回到了最開始遇到的問題:
<s:element ref="s:schema" />,
undefined element declaration 's:schema'
at line 85 column 41 of schema
[url]http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl[/url]
具體呼叫程式碼如下:
值得欣慰的是, 在補充了jaxb-impl-2.2.4-1.jar之後, 可以通過動態方式成功呼叫自己建立的WebService服務了, 詳見下節;
[color=red][b]四.使用JaxWsDynamicClientFactory動態呼叫自己建立的WebService服務[/b][/color]
服務介面及實現類很簡單:
介面 com.service.StudentService:
實現類 com.service.impl.StudentServiceImpl:
server類: com.jettyServer.ServerForJetty:
client類:com.client.Test
先啟動JettyServer, 後訪問http://localhost:9000/student?wsdl, 成功重新整理出wsdl, Ok, 服務順利啟動!
再執行Test的main方法, Congratulations! 這次真正使用Dynamic的方式, 在不需要通過wsdl2java生成客戶端java類檔案的情況下, 成功呼叫WebService服務!
至於不能通過這種方式成功呼叫
[url]http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl[/url]
的問題, 還需要在進一步學習Schema和DTD的知識才能解答;
[color=red][b]五.小結:[/b][/color]
雖未能通過Dynamic的方式成功呼叫天氣預報服務, 好歹wsdl2java生成客戶端呼叫類
的方式是可行的.
[color=red][b]六.其他問題:[/b][/color]
6.1.@WebService宣告問題
在"四.使用JaxWsDynamicClientFactory呼叫自己建立的WebService服務"中
自定義服務介面的實現類com.service.impl.StudentServiceImpl的類宣告之前, 僅註釋宣告瞭@WebService, 而沒有後邊的(endpointInterface="com.service.StudentService",
targetNamespace="http://service.com/"), 這時使用動態代理方式呼叫該服務時, 會發生異常:
Exception in thread "main"
org.apache.cxf.common.i18n.UncheckedException: No operation was found with the name {http://impl.service.com/}helloStudent.
大概還是因為WSDL的基礎知識不夠過硬吧, STFG後, 在
http://lost-alien.iteye.com/blog/1175859 找到答案:
[img]http://static.oschina.net/uploads/space/2012/0406/005811_5dLz_184760.png[/img]
在com.service.impl.StudentServiceImpl的類宣告之前, 正確註釋了
@WebService(
endpointInterface="com.service.StudentService", targetNamespace="http://service.com/")之後,
再使用動態方式呼叫該服務, 一切順利!
具體原因還有待分析, 認識和理解!
6.2.關於CXF wsdl2java生成的呼叫遠端服務的客戶端java類檔案
在"四.使用JaxWsDynamicClientFactory呼叫自己建立的WebService服務"中所描述的自定義WebService服務中, 若使用JaxWsServerFactoryBean的呼叫方式, 那麼首先需要通過wsdl2java生成客戶端必需的java類檔案;
將通過自己的wsdl生成的客戶端java類檔案的目錄結構&類名稱,
和wsdl2java http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl
這個wsdl檔案後生成的java類檔案的目錄結構&類名稱, 對比之後, 發現差距明顯:
[img]http://static.oschina.net/uploads/space/2012/0406/005912_lAAn_184760.png[/img]
對比可以清楚的看到, 自己的wsdl生成的客戶端類檔案, 其java類檔名及其混亂, 始終沒能弄懂為什麼會這樣? 還請各位同學多多指教!
實戰CXF呼叫Webxml天氣預報服務
今晚群裡的kasasis同學問我會不會使用CXF呼叫
[url]http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl[/url]
這個天氣預報的WebService服務;
我也是初學者, 在嘗試呼叫的過程中發現不少問題, 也有一些小心得, 希望與大家分享, 更希望大家可以幫我解惑.
[color=red][b]一.初探:通過wsdl2java生成呼叫遠端服務所需要的java類[/b][/color]
因為還沒有成功使用dynamic-clients(http://cxf.apache.org/docs/dynamic-clients.html)的方式動態呼叫過WebService服務, 所以決定使用CXF提供的wsdl2java來生成呼叫WebService服務所必須的java類, 進而使用JaxWsServerFactoryBean來呼叫WebService服務:
[img]http://static.oschina.net/uploads/space/2012/0406/005536_rxYD_184760.png[/img]
遺憾的是, CXF wsdl2java報錯了:
[i]undefined element declaration 's:schema'
at line 85 column 41 of schema [/i]
[url]http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl[/url]
將該wsdl下載下來, 使用MyEclipse 9.0開啟並檢視, 也提示了這一錯誤:
src-resolve.4.2: Error resolving component 's:schema'.
It was detected that 's:schema' is in namespace 'http://www.w3.org/2001/XMLSchema', but components from this namespace are not referenceable from schema document 'file:///D:/workspace/workspace_j2ee/CXFWeatherTest/src/WeatherWebService.asmx.original.wsdl'.
If this is the incorrect namespace, perhaps the prefix of 's:schema' needs to be changed.
If this is the correct namespace, then an appropriate 'import' tag should be added to 'file:///D:/workspace/workspace_j2ee/CXFWeatherTest/src/WeatherWebService.asmx.original.wsdl'.
wsdl報錯部分內容如下(下邊程式碼紅色部分):
<s:element name="getSupportDataSetResponse">
<s:complexType>
<s:sequence>
<s:element
minOccurs="0"
maxOccurs="1"
name="getSupportDataSetResult">
<s:complexType>
<s:sequence>
<s:element ref="s:schema" />
<s:any />
</s:sequence>
</s:complexType>
</s:element>
</s:sequence>
</s:complexType>
</s:element>
作為初學者, 曾在風中葉老師的視訊中學習過關於schema及DTD的一些知識, 但還沒修煉到能解決這一錯誤的程度, 也期待各位同學的積極探索並給出答案;
問題催人奮進, 折衷的辦法總是有的:
<s:any/>既然可以代表任何元素, 為什麼不能代表<s:element ref="xxx"/>元素呢? 於是乎, 憤然刪除<s:element ref="s:schema" />, 勉強算是通過了CXF提供的wsdl驗證工具wsdlvalidator的驗證;
Ok, 繼續之前的步驟, 通過wsdl2java來生成呼叫遠端WebService服務所需要的java類;
一切順利, 生成的類的目錄結構如下:
[img]http://static.oschina.net/uploads/space/2012/0406/005423_iXEa_184760.png[/img]
[color=red][b]二.使用JaxWsProxyFactoryBean呼叫天氣服務[/b][/color]
本工程使用的jar包如下圖示:
[img]http://static.oschina.net/uploads/space/2012/0406/005630_GAWN_184760.png[/img]
通過JaxWsProxyFactoryBean呼叫webService服務的過程相信大家都很熟悉了, 具體程式碼如下:
package cn.com.client;
import java.util.List;
import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import cn.com.webxml.ArrayOfString;
import cn.com.webxml.WeatherWebServiceSoap;
public class Test {
public static void main(String[] args) throws Exception {
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.getInInterceptors().add(new LoggingInInterceptor());
factory.getOutInterceptors().add(new LoggingOutInterceptor());
factory.setAddress(
"http://www.webxml.com.cn/WebServices/WeatherWebService.asmx");
factory.setServiceClass(WeatherWebServiceSoap.class);
WeatherWebServiceSoap client =
(WeatherWebServiceSoap) factory.create();
ArrayOfString o = client.getWeatherbyCityName("南陽");
List<String> strList = o.getString();
for (String str : strList) {
System.out.println(str);
}
}
}
執行還算順利, 得到的結果如下:
資訊: Outbound Message
---------------------------
[color=darkblue]ID: 1
Address: http://www.webxml.com.cn/WebServices/WeatherWebService.asmx
Encoding: UTF-8
Content-Type: text/xml
Headers: {Accept=[*/*], SOAPAction=["http://WebXml.com.cn/getWeatherbyCityName"]}
Payload:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<getWeatherbyCityName xmlns="http://WebXml.com.cn/">
<theCityName>南陽</theCityName>
</getWeatherbyCityName>
</soap:Body>
</soap:Envelope>
河南
南陽
57178
57178.jpg
2012-4-5 22:58:11
11℃/24℃
4月6日 晴
無持續風向微風
0.gif
0.gif
今日天氣實況:氣溫:16℃;風向/風力:北風 0級;溼度:53%;空氣質量:較差;紫外線強度:中等
穿衣指數:建議著薄型套裝等春秋過渡裝。年老體弱者宜著套裝。但晝夜溫差較大,注意適當增減衣服。
感冒指數:晝夜溫差較大,較易發生感冒,請適當增減衣服。體質較弱的朋友請注意防護。
運動指數:天氣較好,趕快投身大自然參與戶外運動,盡情感受運動的快樂吧。
洗車指數:適宜洗車,未來持續兩天無雨天氣較好,適合擦洗汽車,藍天白雲、風和日麗將伴您的車子連日潔淨。
晾曬指數:天氣不錯,適宜晾曬。趕緊把久未見陽光的衣物搬出來吸收一下太陽的味道吧!
旅遊指數:天氣晴朗,風和日麗,溫度適宜,是個好天氣哦。這樣的天氣很適宜旅遊,您可以盡情地享受大自然的風光。
路況指數:天氣較好,路面比較乾燥,路況較好。
舒適度指數:溫度適宜,風力不大,您在這樣的天氣條件下,會感到比較清爽和舒適。
空氣汙染指數:氣象條件較不利於空氣汙染物稀釋、擴散和清除,請適當減少室外活動時間。
紫外線指數:屬中等強度紫外線輻射天氣,外出時建議塗擦SPF高於15、PA+的防曬護膚品,戴帽子、太陽鏡。
11℃/24℃
4月7日 晴
無持續風向微風
0.gif
0.gif
10℃/23℃
4月8日 陰轉多雲
無持續風向微風
2.gif
1.gif
南陽市位於河南省西南部,北靠伏牛山,東扶桐柏山,西依秦嶺,南臨漢江。..................[/color]
[color=red][b]三.使用JaxWsDynamicClientFactory呼叫天氣服務[/b][/color]
CXF關於Dynamic-clients的介紹文件見:
[url]http://cxf.apache.org/docs/dynamic-clients.html[/url]
很簡潔的一段官方示例程式碼:
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient("echo.wsdl");
Object[] res = client.invoke("echo", "test echo");
System.out.println("Echo response: " + res[0]);
但具體的呼叫過程並非一帆風順; 讓人不解的是, 即使呼叫自己所建立的WebService, 使用動態方式呼叫也不能成功, 總會提示一個異常:
Exception in thread "main" java.lang.IllegalStateException: Unable to write generated Java files for schemas: null
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:351)
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:234)
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:227)
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:182)
at com.client.Test.dynamicStudent(Test.java:30)
at com.client.Test.main(Test.java:38)
Caused by: java.lang.reflect.UndeclaredThrowableException
at $Proxy29.build(Unknown Source)
at org.apache.cxf.endpoint.dynamic.DynamicClientFactory.createClient(DynamicClientFactory.java:349)
... 5 more
Caused by: java.lang.NoSuchMethodException:
com.sun.codemodel.internal.JCodeModel.build(java.lang.Object)
at java.lang.Class.getMethod(Class.java:1605)
at org.apache.cxf.common.util.ReflectionInvokationHandler.invoke(ReflectionInvokationHandler.java:50)
... 7 more
異常資訊的最後一個Caused by給了我線索:
java.lang.NoSuchMethodException:
com.sun.codemodel.internal.JCodeModel.build(java.lang.Object)
遍歷工程所用jar檔案, 居然沒有找到internal包下的類JCodeModel;
但報的異常是NoSuchMethodException, 而不是ClassNotFoundException, 表明該類是存在的, 可能包路徑發生了變化, 遂STFG(search the fUcking google. 從陳皓老師的博文學到的 - - 囧), 最終發現該類現存在於jaxb-xjc-2.2.4-1.jar中, 包路徑為com.sun.codemodel, 而不是異常中所提示的com.sun.codemodel.internal;
為什麼會這樣? 難道是我的jaxb-xjc jar包的版本不對?
遂通過http://jaxb.java.net/, 對比jaxb2.0.1 -- 2.2.5之間的所有版本, 均沒有找到包com.sun.codemodel.internal...
Ok, 讓我們繼續查詢jaxb1.x版本的jar包;
幸運的是, 在頁面[url]http://jaxb.java.net/nonav/2.0.1/docs/jaxb-1_0.html [/url], 終於有所發現:
JAXB 2.0 is backwards compatible with JAXB 1.0 - you can deploy your existing 1.0 applications on the 2.0 runtime (provided that you also bundle the jaxb1-impl.jar) and they should run without modification.
檢視我的專案的類庫, 剛好缺少了這麼一個jaxb-impl.jar包,,, 加上該包(我使用的是jaxb-impl-2.2.4-1.jar), 再次執行動態呼叫天氣預報WebService的服務, Congratulations! 這個異常被幹掉了!
但是, 不要高興的太早, 服務並沒有呼叫成功, 因為又回到了最開始遇到的問題:
<s:element ref="s:schema" />,
undefined element declaration 's:schema'
at line 85 column 41 of schema
[url]http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl[/url]
具體呼叫程式碼如下:
package com.client;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
public class Test {
public static void main(String[] args) throws Exception {
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient(
"http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl");
Object[] res = client.invoke("getSupportProvince");
System.out.println("Echo response: " + res[0]);
}
}
值得欣慰的是, 在補充了jaxb-impl-2.2.4-1.jar之後, 可以通過動態方式成功呼叫自己建立的WebService服務了, 詳見下節;
[color=red][b]四.使用JaxWsDynamicClientFactory動態呼叫自己建立的WebService服務[/b][/color]
服務介面及實現類很簡單:
介面 com.service.StudentService:
package com.service;
import javax.jws.WebParam;
import javax.jws.WebService;
@WebService
public interface StudentService {
String helloStudent(@WebParam(name="text")String name);
}
實現類 com.service.impl.StudentServiceImpl:
package com.service.impl;
import javax.jws.WebService;
import com.service.StudentService;
@WebService(endpointInterface="com.service.StudentService", targetNamespace="http://service.com/")
public class StudentServiceImpl implements StudentService{
public String helloStudent(String name) {
return "hello " + name;
}
}
server類: com.jettyServer.ServerForJetty:
package com.jettyServer;
import javax.xml.ws.Endpoint;
import com.service.impl.StudentServiceImpl;
public class ServerForJetty {
public static void main(String[] args) throws InterruptedException {
StudentServiceImpl implementor = new StudentServiceImpl();
String address = "http://localhost:9000/student";
Endpoint.publish(address, implementor);
}
}
client類:com.client.Test
package com.client;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
public class Test {
public static void main(String[] args) throws Exception {
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient("http://localhost:9000/student?wsdl");
Object[] res = client.invoke("helloStudent", "LeeThinker");
System.out.println("Echo response: " + res[0]);
}
}
先啟動JettyServer, 後訪問http://localhost:9000/student?wsdl, 成功重新整理出wsdl, Ok, 服務順利啟動!
再執行Test的main方法, Congratulations! 這次真正使用Dynamic的方式, 在不需要通過wsdl2java生成客戶端java類檔案的情況下, 成功呼叫WebService服務!
至於不能通過這種方式成功呼叫
[url]http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl[/url]
的問題, 還需要在進一步學習Schema和DTD的知識才能解答;
[color=red][b]五.小結:[/b][/color]
雖未能通過Dynamic的方式成功呼叫天氣預報服務, 好歹wsdl2java生成客戶端呼叫類
的方式是可行的.
[color=red][b]六.其他問題:[/b][/color]
6.1.@WebService宣告問題
在"四.使用JaxWsDynamicClientFactory呼叫自己建立的WebService服務"中
自定義服務介面的實現類com.service.impl.StudentServiceImpl的類宣告之前, 僅註釋宣告瞭@WebService, 而沒有後邊的(endpointInterface="com.service.StudentService",
targetNamespace="http://service.com/"), 這時使用動態代理方式呼叫該服務時, 會發生異常:
Exception in thread "main"
org.apache.cxf.common.i18n.UncheckedException: No operation was found with the name {http://impl.service.com/}helloStudent.
大概還是因為WSDL的基礎知識不夠過硬吧, STFG後, 在
http://lost-alien.iteye.com/blog/1175859 找到答案:
[img]http://static.oschina.net/uploads/space/2012/0406/005811_5dLz_184760.png[/img]
在com.service.impl.StudentServiceImpl的類宣告之前, 正確註釋了
@WebService(
endpointInterface="com.service.StudentService", targetNamespace="http://service.com/")之後,
再使用動態方式呼叫該服務, 一切順利!
具體原因還有待分析, 認識和理解!
6.2.關於CXF wsdl2java生成的呼叫遠端服務的客戶端java類檔案
在"四.使用JaxWsDynamicClientFactory呼叫自己建立的WebService服務"中所描述的自定義WebService服務中, 若使用JaxWsServerFactoryBean的呼叫方式, 那麼首先需要通過wsdl2java生成客戶端必需的java類檔案;
將通過自己的wsdl生成的客戶端java類檔案的目錄結構&類名稱,
和wsdl2java http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?wsdl
這個wsdl檔案後生成的java類檔案的目錄結構&類名稱, 對比之後, 發現差距明顯:
[img]http://static.oschina.net/uploads/space/2012/0406/005912_lAAn_184760.png[/img]
對比可以清楚的看到, 自己的wsdl生成的客戶端類檔案, 其java類檔名及其混亂, 始終沒能弄懂為什麼會這樣? 還請各位同學多多指教!
相關文章
- Java呼叫取得天氣預報WebServicesJavaWeb
- 通過iframe呼叫天氣預報&jsonpJSON
- Flutter實踐:天氣預報Flutter
- 天氣預報查詢 API 提供個性化的天氣服務的設計思路API
- 全國天氣預報資訊資料 API 功能簡介與程式碼呼叫實戰視訊API
- 天氣預報apiAPI
- Android呼叫天氣預報的WebService簡單例子AndroidWeb單例
- 天氣預報戰略升級為“新晴天氣”,深耕天氣+出行生活場景
- flutter天氣預報APPFlutterAPP
- 天氣預報API介面API
- 天氣預報介面收集
- CXF實現webService服務(一)Web
- 中央氣象局天氣預報介面---java實現Java
- 中國天氣網免費天氣預報介面APIAPI
- axis WebServices 完美呼叫天氣預報,查詢、顯示 程式碼!Web
- react native天氣預報React Native
- Delphi天氣預報查詢
- 天氣預報程式碼大全
- React實戰之React+Redux實現一個天氣預報小專案ReactRedux
- Knative 實戰:基於 Knative Serverless 技術實現天氣服務-下篇Server
- grpc實戰——服務端流式呼叫RPC服務端
- 查詢天氣預報網站網站
- Python 獲取當地未來五天天氣 天氣預報 獲取天氣Python
- Android Spinner(級聯 天氣預報)Android
- 5.22 天氣預報系統 小
- 0828-T3 天氣預報
- 天氣預報API,你想要的它都有API
- php,java獲取天氣預報程式碼PHPJava
- 基於Qt的天氣預報專案QT
- Rust採集天氣預報資訊並實時更新資料Rust
- 使用CXF開發RESTFul服務REST
- Dapr + .NET Core實戰(十二)服務呼叫之GRPCRPC
- 天氣預報的功能實現(使用聚合的提供的外部介面)
- Mac天氣預報元件:Weather Widget Live for MacMac元件
- 開發chrome外掛入門-天氣預報Chrome
- 實現微服務預熱呼叫之後再開始服務(上)微服務
- 實現微服務預熱呼叫之後再開始服務(下)微服務
- 天氣預報更名“新晴天氣”,品牌升級助力智慧生活