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 的时候 , 也照样正常 . 真晕了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值