Java与C#平台通信 WCF CXF SOAP
問題提出?:
采用的方案?:
基于?C#平臺的?SOA框架?---WCF簡介
WCF?平臺搭建
JAVA?調用?WCF
基于?Java平臺的?SOA框架?---CXF簡介
CXF平臺搭建
CXF?框架支撐環境
開發環境準備
接口類創建
消費服務
使用會話的調用方式?:
C#?調用?CXF Service
使用會話的調用方式
WCF與?CXF調用的異常
Java?層拋出?:?服務器未能識別?HTTP?頭?SOAPAction?的值異常
?
<!-- /* Font Definitions */ @font-face {font-family:宋體; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"/@宋體"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋體; mso-font-kerning:1.0pt;} h1 {mso-style-link:"標題 1 Char"; mso-style-next:正文; margin-top:2.5pt; margin-right:0cm; margin-bottom:2.5pt; margin-left:0cm; mso-para-margin-top:.5gd; mso-para-margin-right:0cm; mso-para-margin-bottom:.5gd; mso-para-margin-left:0cm; mso-pagination:none; page-break-after:avoid; mso-outline-level:1; font-size:16.0pt; mso-bidi-font-size:12.0pt; font-family:"Times New Roman"; mso-font-kerning:1.0pt; font-weight:bold; mso-bidi-font-weight:normal;} h2 {mso-style-name:"標題 2/,Chapter X/.X/. Statement/,h2/,2/,Header 2/,l2/,Level 2 Head/,heading 2"; mso-style-link:"標題 2 Char/,Chapter X/.X/. Statement Char/,h2 Char/,2 Char/,Header 2 Char/,l2 Char/,Level 2 Head Char/,heading 2 Char"; mso-style-next:正文; mso-margin-top-alt:auto; margin-right:0cm; mso-margin-bottom-alt:auto; margin-left:0cm; mso-pagination:lines-together; page-break-after:avoid; mso-outline-level:2; font-size:14.0pt; mso-bidi-font-size:16.0pt; font-family:Arial; mso-bidi-font-family:"Times New Roman"; mso-font-kerning:1.0pt; font-weight:bold;} p.MsoHeader, li.MsoHeader, div.MsoHeader {margin:0cm; margin-bottom:.0001pt; text-align:center; mso-pagination:none; tab-stops:center 207.65pt right 415.3pt; layout-grid-mode:char; border:none; mso-border-bottom-alt:solid windowtext .75pt; padding:0cm; mso-padding-alt:0cm 0cm 1.0pt 0cm; font-size:9.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋體; mso-font-kerning:1.0pt;} p.MsoFooter, li.MsoFooter, div.MsoFooter {margin:0cm; margin-bottom:.0001pt; mso-pagination:none; tab-stops:center 207.65pt right 415.3pt; layout-grid-mode:char; font-size:9.0pt; font-family:"Times New Roman"; mso-fareast-font-family:宋體; mso-font-kerning:1.0pt;} p.MsoTitle, li.MsoTitle, div.MsoTitle {margin-top:12.0pt; margin-right:0cm; margin-bottom:3.0pt; margin-left:0cm; text-align:center; mso-pagination:none; mso-outline-level:1; font-size:16.0pt; font-family:Arial; mso-fareast-font-family:宋體; mso-font-kerning:1.0pt; font-weight:bold;} a:link, span.MsoHyperlink {color:blue; text-decoration:underline; text-underline:single;} a:visited, span.MsoHyperlinkFollowed {color:purple; text-decoration:underline; text-underline:single;} p {mso-margin-top-alt:auto; margin-right:0cm; mso-margin-bottom-alt:auto; margin-left:0cm; mso-pagination:widow-orphan; font-size:12.0pt; font-family:宋體; mso-bidi-font-family:宋體;} code {mso-ansi-font-size:12.0pt; mso-bidi-font-size:12.0pt; font-family:宋體; mso-ascii-font-family:宋體; mso-fareast-font-family:宋體; mso-hansi-font-family:宋體; mso-bidi-font-family:宋體;} span.smalltitle {mso-style-name:smalltitle;} span.1Char {mso-style-name:"標題 1 Char"; mso-style-locked:yes; mso-style-link:"標題 1"; mso-ansi-font-size:16.0pt; mso-bidi-font-size:12.0pt; font-family:宋體; mso-fareast-font-family:宋體; mso-font-kerning:1.0pt; mso-ansi-language:EN-US; mso-fareast-language:ZH-CN; mso-bidi-language:AR-SA; font-weight:bold; mso-bidi-font-weight:normal;} span.2Char {mso-style-name:"標題 2 Char/,Chapter X/.X/. Statement Char/,h2 Char/,2 Char/,Header 2 Char/,l2 Char/,Level 2 Head Char/,heading 2 Char"; mso-style-locked:yes; mso-style-link:"標題 2/,Chapter X/.X/. Statement/,h2/,2/,Header 2/,l2/,Level 2 Head/,heading 2"; mso-ansi-font-size:14.0pt; mso-bidi-font-size:16.0pt; font-family:Arial; mso-ascii-font-family:Arial; mso-fareast-font-family:宋體; mso-hansi-font-family:Arial; mso-font-kerning:1.0pt; mso-ansi-language:EN-US; mso-fareast-language:ZH-CN; mso-bidi-language:AR-SA; font-weight:bold;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:595.3pt 841.9pt; margin:70.9pt 3.0cm 70.9pt 3.0cm; mso-header-margin:42.55pt; mso-footer-margin:42.55pt; mso-paper-source:0; layout-grid:17.5pt .7pt; mso-layout-grid-char-alt:2824;} div.Section1 {page:Section1;} -->
問題提出?:
采用的方案?:
Java?和?C#?的互操作性?,?采用基于?Soap?的通信協議
基于?C#?平臺的?SOA?框架?---WCF?簡介
什么是?WCF?
根據微軟官方的解釋,?WCF?是使用托管代碼建立和運行面向服務?(Service Oriented)?應用程序的統一框架。它使得開發者能夠建立一個跨平臺的、安全、可信賴、事務性的解決方案,且能與已有系統兼容協作。?WCF?是微軟分布?式應用程序開發的集大成者,它整合了?.Net?平臺下所有的和分布式系統有關的技術,例如?.Net Remoting、?ASMX?、?WSE?和?MSMQ?。以通信?(Communiation)?范圍而論,它可以跨進程、跨機器、跨子網、企業網乃至于?Internet?;以宿主程序而論,可以以?ASP.NET?,?EXE?,?WPF?,?Windows Forms?,?NT Service?,?COM+?作為宿主?(Host)?。?WCF?可以支持的協議包括?TCP?,?HTTP?,跨進程以及自定義,安全模式則包括?SAML?,Kerberos?,?X509?,用戶?/?密碼,自定義等多種標準與模式。
?http://blog.csdn.net/antswallow
WCF?平臺搭建
JAVA?調用?WCF
DynamicClientFactory dcf = DynamicClientFactory.newInstance();?
org.apache.cxf.endpoint.Client client=
dcf.createClient("http://localhost:37563/WebSite4/Service.asmx?wsdl");?
Object[] reply = client.invoke("HelloWorld", new Object[]{});?
System.out.println("Server said: " + reply[0].toString());???
基于?Java?平臺的?SOA?框架?---CXF?簡介
詳見?: http://cxf.apache.org/
Apache CXF = Celtix + XFire?,?Apache CXF?的前身叫?Apache CeltiXfire?,現在已經正式更名為?Apache CXF了,以下簡稱為?CXF?。?CXF?繼承了?Celtix?和?XFire?兩大開源項目的精華,提供了對?JAX-WS?全面的支持,并且提供了多種?Binding?、?DataBinding?、?Transport?以及各種?Format?的支持,并且可以根據實際項目的需要,采用代碼優先(?Code First?)或者?WSDL?優先(?WSDL First?)來輕松地實現?Web Services?的發布和使用。Apache CXF?是一個開源的?Services?框架,?CXF?幫助您利用?Frontend?編程?API?來構建和開發?Services?,像JAX-WS?。這些?Services?可以支持多種協議,比如:?SOAP?、?XML/HTTP?、?RESTful HTTP?或者?CORBA?,并且可以在多種傳輸協議上運行,比如:?HTTP?、?JMS?或者?JBI?,?CXF?大大簡化了?Services?的創建,同時它繼承了?XFire?傳統,一樣可以天然地和?Spring?進行無縫集成。
CXF?平臺搭建
從?cxf?官方網站下載最新的發行包?(?當前為?apache-cxf-2.2.3?版本?) ,?解壓目錄結構如下所示?:?
文件目錄結構及相關文件的詳細說明:
bin?(目錄)
bin?目錄中是?CXF?框架中所提供的代碼生成、校驗、管理控制臺工具:
Java to WSDL : java2wsdl
CXF Management Console Tool : mc
WSDL to Java : wsdl2java
WSDL to Service : wsdl2service
WSDL to SOAP : wsdl2soap
WSDL to XML : wsdl2xml
WSDL Validation : wsdlvalidator
XSD to WSDL : xsd2wsdl
docs?(目錄)
CXF?所有類(?class?)對應的?API?文檔,為開發者使用?CXF?完成應用開發提供應有的幫助。
etc?(目錄)
包含一個基本的?Service?暴露所需要的?web.xml?文件,及其它的配置文件。
lib?(目錄)
lib?目錄中包含?CXF?及其運行時所需要的和可選的第三方支持類包(?.jar?文件),可以根據不同項目所需的?CXF特性選擇所需要的支持類包。如果不想一一去區分的話,可以直接在?Web?項目中包含所有的?CXF?及其運行時所需要的第三方支持類包(?.jar?文件)即可。
其中?cxf-2.0.2-incubator.jar?是?CXF?框架的二進制包文件,包含了全部的模塊(?modules?),?cxf-manifest-incubator.jar?是列表清單文件?manifest jar?。
以下的?jar?包是所有?CXF?項目所必需的:
cxf.jar
commons-logging.jar
geronimo-activation.jar (Or the Sun equivalent)
geronimo-annotation.jar (Or the Sun equivalent)
geronimo-javamail.jar (Or the Sun equivalent)
neethi.jar
jaxb-api.jar
jaxb-impl.jar
stax-api.jar
XmlSchema.jar
wstx-asl.jar
xml-resolver.jar
對于?Java2WSDL?和?WSDL2Java?,除了必需的之外,還需要再增加如下?jar?包:
jaxb-xjc.jar
veliocity.jar
velocity-dep.jar
為了支持?JAX-WS?,除了必需的之外,還需要再增加如下?jar?包:
jaxws-api.jar
saaj-api.jar
saaj-impl.jar
asm.jar?(可選的,但是可以提升包裝類型的性能)
為了支持?XML?配置,除了必需的之外,還需要再增加如下?jar?包:
aopalliance.jar
spring-beans.jar
spring-context.jar
spring-core.jar
spring.web.jar
為了獨立的?HTTP?服務支持,除了必需的之外,還需要再增加如下?jar?包:
geronimo-servlet.jar
jetty.jar
jetty-sslengine.jar
jetty-util.jar
sl4j.jar & sl4j-jdk14.jar?(可選的,但是可以提升日志?logging?)
為了支持?Aegis?,除了必需的之外,還需要再增加如下?jar?包:
jaxen.jar
jdom.jar
stax-utils.jar
為了支持?WS-Security?,除了必需的之外,還需要再增加如下?jar?包:
bcprov-jdk14.jar
wss4j.jar
xalan.jar
xmlsec.jar
為了支持?HTTP Binding?,除了必需的之外,還需要再增加如下?jar?包:
jra.jar
jettison.jar?(僅為?JSON?服務所需的)
licenses?(目錄)
列表了引用第三方?jar?包的相關許可協議。
modules?(目錄)
modules?目錄中包含了?CXF?框架根據不同特性分開進行編譯的二進制包文件。發布基于?CXF?框架的?Web?項目時,可以選擇使用該目錄下的所有?.jar?文件,也可以選擇?lib?目錄中的?cxf-2.2.3.jar?文件。
samples?(目錄)
samples?目錄中包含了所有隨?CXF?二進制包發布的示例,包含這些示例的源代碼和相關?Web?應用配置文件,可以方便地用?Ant?來編譯運行測試這些示例,來了解?CXF?的開發和使用的方法。可以通過?samples?目錄和它各個子目錄下的?README.txt?的文件來詳細了解示例的編譯與運行的步驟。
DISCLAIMER?由于仍是處于?Apache?孵化狀態的項目,這里描述了一些說明。
LICENSE?文件中包含了?CXF?框架的授權協議?Apache License Version 2.0?。
NOTICE?羅列了?CXF?框架用到的相關第三方組件的授權協議以其它的相關信息。
README?文件中包含了?CXF?框架本身的一些簡要說明。
release_notes.txt?包含了?CXF?發布時的一些信息,包括運行時所需要的環境,修復?BUG?的列表等。
CXF?框架支撐環境
CXF?框架是一種基于?Servlet?技術的?SOA?應用開發框架,要正常運行基于?CXF?應用?框架開發的企業應用,除了CXF?框架本身之外,還需要?JDK?和?Servlet?容器的支持。
JDK?版本選擇、下載和安裝
CXF?支持非常多的特性,其中不同的特性對?JDK?版本的要求有所不同,但是?JDK?最低的版本是需要選擇?JDK 5或者以上版本。。為了運行?CXF?攜帶的?samples?目錄下的所有示例,還需要?Apache Ant 1.6.5?或以上的版本。為了使用?CXF?的?WS-Security?特性,還需要?Bouncy Castle?,并增加到?CLASSPATH?中。
Servlet?容器下載和安裝
CXF?是一種基于?Servlet?技術的?SOA?應用開發框架,需要?Servlet?容器的支持。CXF?支持在多種?Servlet?容器中運行,包括?WebSphere?、WebLogic?、Tomcat?、Jetty?等。
開發環境準備
為了方便開發,?采用Myeclipse?作為集成開發環境,?并將cxf?發布包lib?目錄下的所有lib?文件加入classpath?中.
接口類創建
在項目的?src?目錄中新建一個?ws.cxf?包,并在里面創建接口類?ISurveyService.java?,為了簡單示示例起見,僅創建一個方法?public String vote(String username,int point);?這里要注意的是在接口上用?@WebService注解標明這是一個即將暴露為?Web Service?的接口,并將里面的方法都暴露出去。完整的接口代碼清單如下:
package?ws.cxf;
?
import?javax.jws.WebService;
?
@WebService
public?interface?ISureyService {
????public?String vote(String name,?int?point);
}
接下來,根據接口的定義,來實現。
package?ws.cxf;
?
import?javax.jws.WebService?;
?
@WebService
public?class?SureyService?implements?ISureyService {
????public?String vote(String name,?int?point) {
???????System.?out?.println(?"?感謝您的投票?"?);
???????return?name+point;
????}
}
Spring?配置
在?src?目錄中創建?beanRefServer.xml?文件,用來定義?Spring?的?Bean?的配置,?CXF?支持?Spring 2.0 Schema?標簽配置方式,并且提供快捷暴露?Web Services?的標簽。
首先,我們需要引入?Spring?與?CXF?的命名空間(?namespace?),如下:
| <beans xmlns="http://www.springframework.org/schema/beans" ????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ????xmlns:jaxws="http://cxf.apache.org/jaxws" ????xsi:schemaLocation=" ????????http://www.springframework.org/schema/beans ????????http://www.springframework.org/schema/beans/spring-beans-2.0.xsd ????????http://cxf.apache.org/jaxws ????????http://cxf.apache.org/schemas/jaxws.xsd"> |
?
這樣,我們可以使用?Spring?與?CXF?的標簽配置了。接著,我們需要引入我們所需要的?CXF?的?Bean?定義文件,如下:
| ????<!-- Import Apache CXF Bean Definition --> ????<import resource="classpath:META-INF/cxf/cxf.xml"/> ????<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/> ????<import resource="classpath:META-INF/cxf/cxf-servlet.xml"/> |
?
接著定義我們具體實現的?Bean?,這個?Bean?的定義與?Spring?普通的?Bean?定義是一樣的:
| ????<!-- SurveyService --> ????<bean id="surveyService" class="ws.cxf.impl.SurveyService"> ????????<property name="excludeName" value="Michael"/> ????????<property name="leastPonit" value="10"/> ????</bean> |
?
最后,將定義的?Bean?暴露出去成為?Web Service?服務,通過?CXF?提供的?Schema?標簽配置<jaxws:server>?,這樣定義的配置顯得更加簡潔與方便,定義如下:
| ????<!-- Expose SurveyWebService --> ????<jaxws:server id="surveyWebService" ????????serviceClass="ws.cxf.ISurveyService" ????????address="/SurveyWebService"> ????????<jaxws:serviceBean> ????????????<ref bean="surveyService"/> <!--?要暴露的?bean?的引用?--> ????????????</jaxws:serviceBean> ????</jaxws:server> |
?
在配置中,?serviceClass?的值是接口類的名稱,?address?為將要暴露出去的?Web Service?訪問地址。比如:?/SurveyWebService?,?那么客戶端消費?Web Service?的地址就會成為http://host:port/WebAPPName/SurveyWebService?,與之相應的?WSDL?地址則為:http://host:port/WebAPPName/SurveyWebService?wsdl?。
?
Web?應用配置
由于我們的示例是需要通過?Servlet?容器進行服務暴露,因此需要配置相對應的?web.xml?文件,首先是增加Spring?的配置文件加載?Listener?,如下:
| ????<!-- Spring Config Location --> ????<context-param> ????????<param-name>contextConfigLocation</param-name> ????????<param-value>/WEB-INF/classes/beanRefServer.xml</param-value> ????</context-param> ????<!-- Spring ContextLoaderListener --> ????<listener> ????????<listener-class> ????????????org.springframework.web.context.ContextLoaderListener ????????</listener-class> ????</listener> |
?
接下來配置?CXF Servlet?的定義,以及它的映射,如下:
| ????<!-- Apache CXFServlet --> ????<servlet> ????????<servlet-name>CXFServlet</servlet-name> ????????<display-name>CXF Servlet</display-name> ????????<servlet-class> ????????????org.apache.cxf.transport.servlet.CXFServlet ????????</servlet-class> ????????<load-on-startup>1</load-on-startup> ????</servlet> ????<!-- CXFServlet Mapping --> ????<servlet-mapping> ????????<servlet-name>CXFServlet</servlet-name> ????????<url-pattern>/*</url-pattern> ????</servlet-mapping> |
?
將之映射為?/*?。這樣,服務端的代碼與配置就全部完成了,接下來就是將應用程序部署到?Web?容器中去,并驗證服務是否正常發布。
?
啟動服務
這時開始啟動?Tomcat?,在啟動的過程中,可以在啟動窗口上看到以鏈接方式部署的應用在啟動中會打印出一些相關信息來,最后顯示啟動成功。?通過訪問?http://localhost:8080/CXF_Spring_Survey/?可以看到?CXF?暴露的服務鏈接:
圖?7. CXF?暴露的服務鏈接的內容示意圖?
可以直接點擊進去,或者手工輸入?WSDL?的地址進行訪問:http://localhost:8080/CXF_Spring_Survey/SurveyWebService?wsdl?,可以看到如下的?WSDL?內容:
圖?8. SurveyWebService?的?WSDL?內容示意圖?
這樣,我們可以確定我們的服務真正發布成功了,接下來就可以利用客戶端進行消費了。
消費服務
回?到?Eclipse?開發平臺,開始編寫消費服務相關的代碼,首先通過?Spring?與?CXF?的配置來定義?Web Service?的客戶端?Bean?,在?src?目錄下創建?beanRefClient.xml?配置文件,同樣,也需要引入?Spring?與?CXF?命名空間的聲明,并引入?CXF?的?Bean?的定義文件,最后通過與服務端配置相對的?CXF?標簽?<jaxws:client>?來定義客戶端訪問服務的聲明,完整的定義內容如下:
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" ????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ????xmlns:jaxws="http://cxf.apache.org/jaxws" ????xsi:schemaLocation=" ????????http://www.springframework.org/schema/beans ????????http://www.springframework.org/schema/beans/spring-beans-2.0.xsd ????????http://cxf.apache.org/jaxws ????????http://cxf.apache.org/schemas/jaxws.xsd"> ????<!-- Import Apache CXF Bean Definition --> ????<import resource="classpath:META-INF/cxf/cxf.xml"/> ????<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/> ????<import resource="classpath:META-INF/cxf/cxf-servlet.xml"/> ? ????<!-- SurveyWebService Client --> ????<jaxws:client id="surveyServiceClient" ????????serviceClass="ws.cxf.ISurveyService" ????????address="http://localhost:8080/CXF_Spring_Survey/SurveyWebService"/> </beans> |
?
定義說明:?id?為?Spring?定義的?id?,用來在程序里進行獲取它的標識,?serviceClass?仍是為服務端定義的接口類,?address?為完整的?Web Service?地址,這個與服務端的定義不一樣。
定義完配置文件,接下來編寫訪問的具體代碼,在?test?目錄下創建?ws.cxf.client?包,然后創建SurveyServiceClient.java?,完整的代碼如下:
| package ws.cxf.client; ? import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import ws.cxf.ISurveyService; ? public class SurveyServiceClient { ???????public static void main(String[] args) ???????{ ??????????????//?加載客戶端的配置定義 ??????????????ApplicationContext context = new ????????????????????????????ClassPathXmlApplicationContext("beanRefClient.xml"); ??????????????//?獲取定義的?Web Service Bean ??????????????ISurveyService surveyService = ?????????????????????(ISurveyService)context.getBean("surveyServiceClient"); ??????????????// 1?、定義調查投票的變量與內容,用來發送給服務 ??????????????String username = "Test"; ??????????????int point = 88; ??????????????//?調用方法進行服務消費 ??????????????String result = surveyService.vote(username,point); ??????????????System.out.println("Result:" + result); ???????} } |
直接運行以上客戶端消費程序,并得到結果如下:
| Result: Test88 |
?
使用會話的調用方式?:
目前還沒有找到如何獲取Http Head?頭信息,?只能人為的將cookie?值回傳給客戶端,?如下:
服務器端代碼:
????public?String register(String name){
?????HttpSession session=CommonFilter.getSession?();
????session.setAttribute(?"test"?, name);
???????String res=session.getId();
????return?"JSESSIONID="?+res;
????}
客戶端代碼?:
???????DynamicClientFactory dcf = DynamicClientFactory.newInstance?();?
???????org.apache.cxf.endpoint.Client client = dcf.createClient("http://localhost:8081/Terminal/cxf/SurveyWebService?wsdl"?);
???????Object[] reply = client.invoke(?"register"?,?new?Object[]{?"goldant"?});
???????//?設置?cookie
?????????HTTPConduit http = (HTTPConduit) client.getConduit();
?????????HTTPClientPolicy httpClientPolicy =?new?HTTPClientPolicy();
?????????httpClientPolicy.setConnectionTimeout(36000);
?????????httpClientPolicy.setAllowChunking(?false?);
?????????httpClientPolicy.setCookie(reply[0].toString()); //?設置?cookie?值
?????????http.setClient(httpClientPolicy);
?
C#?調用?CXF Service
(?詳見?:?動態創建客戶端?http://www.rainsts.net/article.asp?id=304)
using System.IO;
using System.Reflection;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Web.Services;
using System.Web.Services.Description;
using System.Web.Services.Protocols;
using System.Xml.Serialization;
// 1.?使用?WebClient?下載?WSDL?信息。
WebClient web = new WebClient();
Stream stream = web.OpenRead("http://localhost:8081/Terminal/cxf/SurveyWebService?wsdl");
// 2.?創建和格式化?WSDL?文檔。
ServiceDescription description = ServiceDescription.Read(stream);
?
// 3.?創建客戶端代理代理類。
ServiceDescriptionImporter importer = new ServiceDescriptionImporter();
importer.ProtocolName = "Soap"; //?指定訪問協議。
importer.Style = ServiceDescriptionImportStyle.Client; //?生成客戶端代理。
importer.CodeGenerationOptions = CodeGenerationOptions.GenerateProperties | CodeGenerationOptions.GenerateNewAsync;
importer.AddServiceDescription(description, null, null); //?添加?WSDL?文檔。
// 4.?使用?CodeDom?編譯客戶端代理類。
CodeNamespace nmspace = new CodeNamespace(); //?為代理類添加命名空間,缺省為全局空間。
CodeCompileUnit unit = new CodeCompileUnit();
unit.Namespaces.Add(nmspace);
?
ServiceDescriptionImportWarnings warning = importer.Import(nmspace, unit);
CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
CompilerParameters parameter = new CompilerParameters();
parameter.GenerateExecutable = false;
parameter.GenerateInMemory = true;
parameter.ReferencedAssemblies.Add("System.dll");
parameter.ReferencedAssemblies.Add("System.XML.dll");
parameter.ReferencedAssemblies.Add("System.Web.Services.dll");
parameter.ReferencedAssemblies.Add("System.Data.dll");
CompilerResults result = provider.CompileAssemblyFromDom(parameter, unit);
// 5.?使用?Reflection?調用?WebService?。
if (!result.Errors.HasErrors)
{
???????Assembly asm = result.CompiledAssembly;
???????Type t = asm.GetType("ISureyServiceService"); //?如果在前面為代理類添加了命名空間,此處需要將命名空間添加到類型前面。
?
???????object o = Activator.CreateInstance(t);
???????MethodInfo method = t.GetMethod("vote");
???????Console.WriteLine(method.Invoke(o, new object[]{"aaa",100}));
}
?
?
?
使用會話的調用方式?(?暫時未找到相關可用的資料?)
?
?
?
將多個服務發布在同一個?URL?上
http://opensourceforce.org/thread-2797-1-7.html
WCF?與?CXF?調用的異常
Java?層拋出?:?服務器未能識別?HTTP?頭?SOAPAction?的值異常
解決辦法:服務器未能識別?HTTP?標頭?SOAPAction?的值
2009-05-26 14:33:20 @?墨爾本?所屬分類:?Web Service
本文主要探討跨平臺調用?Web Service?出現:?"?服務器未能識別?HTTP?標頭?SOAPAction?的值?"?的解決辦法。
癥狀一:
Web Service + ASP.NET?應用程序部署到服務器默認目錄中,在?IE?中用?http://<?服務器地址?>/<?程序目錄名?>/<默認啟動頁面名?>?發?生?“?服務器未能識別?HTTP?標頭?SOAPAction?的值?”?錯誤。
癥狀二:
在?Java?平臺上調用?.NET Web Service?的服務時,出現?"?服務器未能識別?HTTP?標頭?SOAPAction?的值?"?。
癥狀三:
在?Java?平臺下調用?.NET WEB Service?,出現數據時有時無。
解決對策:
給?.NET?的?WebService?類(即?.asmx?文件下的類)添加屬性[SoapDocumentService(RoutingStyle=SoapServiceRoutingStyle.RequestElement)]
小知識:
什么是?SoapAction??它在?WSDL?中有何作用?
SOAPAction HTTP request header?被用來標識?SOAP HTTP?請求的目的地,其值是個?URI?地址。?SOAP?發送并不限制格式、?URI?特征或其必須可解析,那么在這種情況下,發送一個?HTTP SOAP?請求時,其?HTTP?客戶端必須使用?/?指明?SOAPAction HTTP request header?。
SOAPAction header?的內容可以被用在服務端,諸如:防火墻適當的過濾基于?HTTP?的?SOAP?請求消息等場景。?SOAPAction header?的值為空串?("")?表示?SOAP?消息的目的地由?HTTP?請求的?URI?標識;無值則表示沒有指定這條消息的目的地。
?
org.w3c.dom.Document is an interface, and JAXB can't handle interfaces.
試圖暴露此接口的時候?,?????public Integer UpdateProxyInfo(Document doc,String curIP);
出現了?jaxb?無法綁定接口的錯誤?,?看來?jaxb?對繼承啥的估計不支持
?
cxf:
Jaxb?不允許參數為接口如?document,Map,?除了?List?這種常用的外
jaxb?自定義對象必需要求默認構造函數
cxf annoation?對于自定義對象?,?屬性不允許有包含部份?,?如?myfield??myfieldXXX?這是不允許的
?
開源的世界就是?BUG?的王國?:??(?各種包沖突還真是煩人?)
Caused by: java.lang.NullPointerException
????????at com.ctc.wstx.sw.BaseNsStreamWriter.doWriteAttr(BaseNsStreamWriter.java:468)
?
?
CXF?竟然并是根據接口生成?wsdl….?還要我把實現也注釋掉?????可能是?classes?沒生成的原因
?
注意調用參數一定要對準類型
?
?
com.ctc.wstx.exc.WstxEOFException: Unexpected EOF in prolog?
at [row,col {unknown-source}]: [1,0]?
*********************?
關閉卡巴斯基后,問題得到解決!!
?
?
郁悶?,?如果?wsdl?過大?,?其結果是
java?的?DynamicClientFactory dcf = DynamicClientFactory.newInstance();
會出現一系列網絡錯誤?,?如?socket?關閉等
?
?
?
在用
???????DynamicClientFactory dcf = DynamicClientFactory.newInstance?();
???????org.apache.cxf.endpoint.Client client = dcf.createClient("http://192.168.1.30:8081/Terminal/cxf/SysuserWS?WSDL"?);
?
???????SysUser su=?new?SysUser();
???????su.?name?=?"hello"?;
???????Object[] reply = client.invoke(?"ISysUserService44addSysUser"?,su);
傳遞自定義對象的時候?,?老出錯?,?郁悶要死
Caused by: javax.xml.bind.JAXBException: class com.centerm.webservice.SysUser nor any of its super class is known to this context.
????at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getBeanInfo(JAXBContextImpl.java:590?)
花了一天的時間?,?沒有解決
?
用這個就正常?:
???????JaxWsProxyFactoryBean factory =?new?JaxWsProxyFactoryBean();
???????factory.getInInterceptors().add(?new?LoggingInInterceptor());
????????factory.getOutInterceptors().add(?new?LoggingOutInterceptor());
???????factory.setServiceClass(ISysuserWS.?class?);
???????factory.setAddress(?"http://192.168.1.30:8081/Terminal/cxf/SysuserWS"?);
???????ISysuserWS client = (ISysuserWS) factory.create();
?
???????SysUser su=?new?SysUser();
???????su.setName(?"j"?);
??????
???????Long reply = client.ISysUserService44addSysUser(su);
???????System.?out?.println(?"Server said: "?+ reply);
?
?
?
現在搞明白該現象中的某個原因?:
Ws?返回的是接口如?List?類型?,?則在?wsdl?中會被映射成?anytpye?類型?,?結果客戶端就無法將其轉換?,?所以要明確List?的泛化類型
?
?
?
org.apache.cxf.binding.soap.SoapFault: Error reading XMLStreamReader.
The issue with the latest comment is fixed in CXF 2.2.2, or by using woodstox instead of the Sun parser.?
In anycase, we now have three issues in one JIRA. I'm going to resolve this. New issues should go to new JIRA's
?
郁悶要死?,?下載了個?woodstox-4.0.5
woodstox-msv-core-1.0.0.jar
woodstox-msv-rng-datatype-1.0.0.jar
woodstox-msv-xsdlib-2.0.0.jar
替換掉正常了?,?還好?,?運氣比較好?,?找到資料?,?不然又要痛苦半死
另外好像和?wstx-asl-3.2.8.jar?及?xfire?之類的沖突
????<?classpathentry?kind?=?"lib"?path?=?"WebRoot/WEB-INF/lib/woodstox-msv-core-1.0.0.jar"?/>
????<?classpathentry?kind?=?"lib"?path?=?"WebRoot/WEB-INF/lib/woodstox-msv-rng-datatype-1.0.0.jar"?/>
????<?classpathentry?kind?=?"lib"?path?=?"WebRoot/WEB-INF/lib/woodstox-msv-xsdlib-2.0.0.jar"?/>???
????<?classpathentry?kind?=?"lib"?path?=?"WebRoot/WEB-INF/lib/wstx-asl-3.2.8.jar"?/>
????<?classpathentry?kind?=?"con"?path?="melibrary.com.genuitec.eclipse.ws.xfire.MYECLIPSE_XFIRE_CORE"?/>
????<?classpathentry?kind?=?"con"?path?="melibrary.com.genuitec.eclipse.ws.xfire.MYECLIPSE_XFIRE_HTTP_CLIENT"?/>
????<?classpathentry?kind?=?"con"?path?="melibrary.com.genuitec.eclipse.ws.xfire.MYECLIPSE_XFIRE_JAXB2"?/>
?
順序改成上面這種就正常了
?
?http://blog.csdn.net/antswallow
?
org.apache.cxf.interceptor.Fault: Could not send Message.
?
在調用?:?????????List<TreeNode4Dwr> sult=
??client.ISysUser4Dwr44getSysUserUserGroupResourceForDwr("1-1");
接口的時候?,?客戶端拋出上面的異常?,?但服務層是有調用到的?,?只是在返回對象的時候?,?拋出了一系列的錯誤?.
懷疑是?Tcp Monitor?的問題?,?客戶端直接調用目標地址?,?結果正常
奇怪的是?,?我前面測試的幾個類似的接口?,?有?tcp monitor?的時候?,?也照樣正常?.?真暈了
總結
以上是生活随笔為你收集整理的Java与C#平台通信 WCF CXF SOAP的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 文科生可以报哪些医学院校(文科生可以报哪
- 下一篇: 老司机给几个网站谢谢(谁有好看的网站)