Java调用.NET的WCF

简介: 最近开始了解WCF。写了个最简单的Helloworld,想通过java客户端实现通信。没想到以我的基础,居然花了整整两天(当然是工作以外的时间,呵呵),整个过程大费周折,特写下此文,以供有需要的朋友参考: 第一步:生成WCF服务 新建WCF解决方案,分别添加三个项目,HelloTimeService(类库),HelloTimehost(控制台程序),HelloTimeClient(控制

最近开始了解WCF。写了个最简单的Helloworld,想通过java客户端实现通信。没想到以我的基础,居然花了整整两天(当然是工作以外的时间,呵呵),整个过程大费周折,特写下此文,以供有需要的朋友参考:

第一步:生成WCF服务

新建WCF解决方案,分别添加三个项目,HelloTimeService(类库),HelloTimehost(控制台程序),HelloTimeClient(控制台程序),项目结构如图:
邀月工作室
各个项目的主要代码:
service:
邀月工作室

Host:
邀月工作室

Client:
邀月工作室

编译通过后,测试Host和Client分别成功:
邀月工作室

邀月工作室

保持Host程序打开,这样,WCF服务就一直可以被外部程序调用。当然也包括Java客户端。

我们看看生成的WSDL

邀月工作室

邀月工作室

第二步:调用WCF生成的WSDL生成java客户端。

首先,请允许我介绍下axis2,它的官方地址:http://ws.apache.org/axis2/

这是一个java平台的web service解决方案。我们最常用的是WSDL2Java和Java2WSDL两个功能。

关于Web service的另一个解决方案是xFire,我没试过。

关于命令行执行WSDL2Java,我也没有执行成功! 我这里介绍的是Code Generator Wizard - eclipse Plug-in,一个Eclipse的插件。而且是在参考了众多解决方案才配置成功!

特别感谢yycxbjl的这篇文章:http://www.cnblogs.com/yycxbjl/archive/2010/06/14/1758063.html

我的Java整个配置环境:

1.安装JDK并配置环境变量

JAVA_HOME=D:/2000/Java/JDKUpdate(注意,不带版本号是为了以后升级时只复制文件,而不必修改环境变量。)
path=%JAVA_HOME%/bin;
classpath=.;%JAVA_HOME%/lib;%JAVA_HOME%/lib/tools.jar

2.下载并安装Eclipse3.6,就是大家熟悉的太阳神Helios(解压即可)
解压到:D:/2000/Java/Eclipse

3.下载Tomcat6.0.29(本文中使用的是绿色版,故解压即完成)
解压到:D:/2000/Java/tomcat(注意,不带版本号是为了以后升级时只复制文件,而不必修改环境变量。)
由于安装的是tomcat6.0不用配置tomcat的环境变量,至于以前的版本可以查资料。
需要设置TOMCAT_HOME,CATAlINA等环境变量


4.从 http://ws.apache.org/axis2/download/1_4_1/download.cgi下载 axis2-1.4.1-bin.zip
解压到:D:/2000/Java/Axis2,注意不要下载Axis2 1.5.1,原因yycxbjl说:“最新版的 1.5.0 与 1.5.1 中没有 backport-util-concurrent-3.1.jar, 无法解决:使用axis2-eclipse-codegen-wizard插件,从wsdl文件生成java文件时出错无法继续的问题,故不使用。)

5.下载1.4.1版的 axis2-eclipse-codegen-wizard 与 axis2-eclipse-service-archiver-wizard

http://ws.apache.org/axis2/tools/1_0/eclipse/wsdl2java-plugin.html#operation1

(但解压后里面显示是1.3.0, 解压到:D:/2000/java/Eclipse/dropins (连压缩包中的根目录一起解压出来)。也可以用传统的link方法部署。

复制 D:/2000/Java/Axis2/lib/backport-util-concurrent-3.1.jar 与 geronimo-stax-api_1.0_spec-1.0.1.jar
到:D:/2000/Java/Eclipse/dropins/Axis2_Codegen_Wizard_1.3.0/lib, 并编辑:D:/2000/Java/Eclipse/dropins/Axis2_Codegen_Wizard_1.3.0/plugin.xml
在 runtime 下 添加
<library name="lib/backport-util-concurrent-3.1.jar">
<export name="*"/>
</library>
<library name="lib/geronimo-stax-api_1.0_spec-1.0.1">
<export name="*"/>
</library>

将Axis2_Codegen_Wizard_1.3.0重命名为Axis2_Codegen_Wizard_1.4.1,(这是整个部署的关键!这里邀月折腾了整整一天!)


新建一个Java project,命名为GetWCFInfoByJavaClient,并在新项目中添加新向导,File-New

此时,我们可以看到期待已久的wizard界面:
邀月工作室

邀月工作室

邀月工作室

邀月工作室

邀月工作室

邀月工作室

此进,在新建的GetWCFInfoByJavaClient项目中建一个package,命名为org.tempuri,与前面自定义的命名空间一致。将生成的两个类文 件,ServiceCallbackHandler.java和ServiceStub.java文件添加进来,并在jreSE1.6库中添加d:/2000/Java/Axis2/lib下所有jar文件的引用。

注意此时有个特殊的文件,即Axis2_Codegen_Wizard_1.4.1/lib/axis2-1.4.1.jar,需要手动复制到d:/2000/java/axis2/lib下并添加到项目的jre库中,这是邀月第二个卡壳的地方,琢磨了好久,慎之慎之。

项目的结构应该如下图:
邀月工作室

eclipse的命名空间提示就是比vs强啊!很喜欢Ctrl+1。呵呵。微软要是能做到这点,那该多好啊!

要命的是,此时库都添加完成,检查代码也无误,居然编译错误,提示:

Access restriction: The type AxisFault is not accessible due to restriction on required library D:/2000/Java/Axis2/lib/axis2-kernel-1.4.1.jar


邀月工作室

这下我傻眼了,于是赶紧google,这两天google.com老是无故罢工,真是祸不单行,终于找到一篇老外的文章,说是如下,即可解决:
* Go to the Build Path settings in the project properties. Windows -> Preferences -> Java Compiler
* Remove the JRE System Library
* Add another JRE with a "perfect match"
* clean and build your project again. It worked for me.

试了下,我的默认jre环境果然是JDK5,于是换为jre system library

邀月工作室


邀月工作室

邀月工作室

终于编译成功!看到曙光了,

邀月工作室

此时,最后的工作就是在Main中调用stub得到我们想要的服务结果了,简单方法,将刚才生成的测试类的方法略作修改,即可运行。如下:
邀月工作室

这正是我们想要的结果。

关于java与.net交互的其他文章,请参考:

微软示例:

Java/.NET Interoperability with the Microsoft.com Web Service
http://msdn.microsoft.com/en-us/library/ms953968.aspx

Interoperability Testing

http://msdn.microsoft.com/en-us/library/aa480510.aspx

IBM示例:使用 Eclipse 和 Java SE 6 创建独立 Web Services 应用程序,第 1 部分: Web Services 服务端应用程序(该链接需要先注册)

https://www6.software.ibm.com/developerworks/cn/education/webservices/ws-eclipse-javase1/section2.html

小结: 这虽然只是一个简单的demo,但我问了许多人,并在论坛发问,可是由于使用环境的不同,最终没找到类似的环境,只好自己摸索实践,好在还有一点点java基础,另外网上几个论坛像javaeye提供的答案过于陈旧,这正是java初学者苦恼之处,这点来看,微软的开发环境无论如何是值得称赞的,至少它不用跑到别的地盘去问答案。eclipse/tomcat/axis等代表的服务器和开发环境、插件配置非常的让初学者无奈!因为你不知道某个jar是 否与其他几千个jar很好的兼容。不知道java高手们是否指一条明道,非常感谢!并再次感谢yycxb

下篇文章介绍WCF客户端如何调用java的web service,那要简单多了。敬请关注。


附:WCF的配置文件:

  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <configuration>
  3. <system.web>
  4. <compilation debug="true" />
  5. </system.web>
  6. <system.serviceModel>
  7. <services>
  8. <service name="Sample.WCF.HelloTimeForJava.Service" behaviorConfiguration="MyServiceTypeBehaviors">
  9. <endpoint address="HelloTimeService" binding="wsHttpBinding" contract="Sample.WCF.HelloTimeForJava.IService">
  10. <identity>
  11. <dns value="localhost" />
  12. </identity>
  13. </endpoint>
  14. <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
  15. <host>
  16. <baseAddresses>
  17. <add baseAddress="http://localhost:8000/" />
  18. </baseAddresses>
  19. </host>
  20. </service>
  21. </services>
  22. <behaviors>
  23. <serviceBehaviors>
  24. <behavior name="MyServiceTypeBehaviors">
  25. <serviceMetadata httpGetEnabled="True" httpGetUrl=""/>
  26. <serviceDebug includeExceptionDetailInFaults="False" />
  27. </behavior>
  28. </serviceBehaviors>
  29. </behaviors>
  30. </system.serviceModel>
  31. </configuration>
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.web> <compilation debug="true" /> </system.web> <system.serviceModel> <services> <service name="Sample.WCF.HelloTimeForJava.Service" behaviorConfiguration="MyServiceTypeBehaviors"> <endpoint address="HelloTimeService" binding="wsHttpBinding" contract="Sample.WCF.HelloTimeForJava.IService"> <identity> <dns value="localhost" /> </identity> </endpoint> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> <host> <baseAddresses> <add baseAddress="http://localhost:8000/" /> </baseAddresses> </host> </service> </services> <behaviors> <serviceBehaviors> <behavior name="MyServiceTypeBehaviors"> <serviceMetadata httpGetEnabled="True" httpGetUrl=""/> <serviceDebug includeExceptionDetailInFaults="False" /> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>


相关链接:












































主要说说JAVA如何调用WCF服务。

  Java环境下生成代理类的工具有很多,如wsdl2Java,wsimport 等。本文中使用的工具是wsimport。

  wsdl2Java 生成命令实例:

  

?
1
wsdl2Java -p packageName -d C:\ProxyClass http: //127.0.0.1/WcfService/TestService.svc?wsdl

  命令说明:

  -p:生成文件的包名称

-d: 生成路径

  后面就是wsdl的地址,如果用服务地址(不带?wsdl)貌似不行

  Java环境下的都是包结构,和C#不一样。

  本文使用wsimport生成代理调用了WCF服务。

  调用步骤:

  1、在Java工程所在的文件夹中建立文件夹,以放置生成的Java文件。如下图:

  

  2、针对不同的服务生成代理,以放在不同的文件夹中:如生成LoginService.svc的命令如下:

  注意以上红色标识部分:为存放的文件夹名称。运行以上命令后生成的文件如下:

  重复1、2 生成其他服务的代理。主要修改的就是存放路径与服务地址。

  3、在工程的src中右键添加包(注意:这里的包名称需通命令中指定的包名次相同),如下图:

4、将生成的文件复制到包中

5、调用:

复制代码
    public static void main(String[] args) {
        // TODO Auto-generated  method stub        
        LoginService loginService=new LoginService();
        ILogin loginProxy= loginService.getBasicHttpBindingILogin();
        String token= loginProxy.login("admin","123456");
        System.out.println(token);
        

    }
复制代码

运行结果:












































使用分布式编程,很方便不同编程语言之间互相访问,但也必须注意一些技术细节,实现起来才能畅通无阻,取得事半功倍的效果。

首先,创建一个WCF。使用原有网站或新建一个网站,并将端口动态改为固定,如设成8000。在网站中添加WCF服务,取名字为:GetAccountService.svc,这时同时生成了一个接口:IGetAccountService.cs和一个实现类:GetAccountService.cs,并且有一个默认方法。我们为了测试对数据库的访问,将方法改为:GetAccount。

完成的代码如下:

1.IGetAccountService.cs

复制代码
 
  
目录
相关文章
|
15天前
|
Java C# 开发者
【干货】Java开发者快速上手.NET指南
【干货】Java开发者快速上手.NET指南
|
3月前
|
网络协议 Java Linux
Java 异常 java.net.UnknownHostException 的原因和解决方案
Java 异常 java.net.UnknownHostException 的原因和解决方案
493 0
|
6月前
|
Java
已解决Java.net.MalformedURLException异常的有效方法java.net.MalformedURLException: no protocol异常处理
已解决Java.net.MalformedURLException异常的有效方法java.net.MalformedURLException: no protocol异常处理
353 0
|
4月前
in thread “main“ java.lang.IllegalArgumentException:java.net.UnknownHostException:hadoop102
in thread “main“ java.lang.IllegalArgumentException:java.net.UnknownHostException:hadoop102
24 0
|
9月前
|
Java
JAVA 端口被占用 报错解决方案:java.net.BindException: Address already in use: bind
JAVA 端口被占用 报错解决方案:java.net.BindException: Address already in use: bind
120 0
|
10月前
|
Java C# C++
【从Java到C#系列 四】从java到.net 核心
【从Java到C#系列 四】从java到.net 核心
70 0
|
10月前
|
存储 Java 编译器
【从Java到C#系列 三】从java到.net 高级
【从Java到C#系列 三】从java到.net 高级
59 0
|
10月前
|
开发框架 IDE Java
【从Java到C#系列 二】从java到.net 基础
【从Java到C#系列 二】从java到.net 基础
78 0
|
Java 程序员 C#
【.Net vs Java? 】 看一看二者的类有多像?(一)
【.Net vs Java? 】 看一看二者的类有多像?
390 0
【.Net vs Java? 】 看一看二者的类有多像?(一)
|
1天前
|
安全 Java 调度
Java线程:深入理解与实战应用
Java线程:深入理解与实战应用
8 0