在没有 Java EE 应用服务器的情况下使用 Web 服务在 C# 和 Java 之间进行互操作?
Posted
技术标签:
【中文标题】在没有 Java EE 应用服务器的情况下使用 Web 服务在 C# 和 Java 之间进行互操作?【英文标题】:Interoperate between C# and Java using web services without a Java EE application server? 【发布时间】:2010-12-14 19:22:38 【问题描述】:我的处境很艰难:我们有一个公开基于 Java 的 API 的第三方企业系统。但是,我们是一个 100% 面向 .Net 的开发团队。本质上,我需要用 C# 代码可以调用的东西来包装 Java API。
Web 服务会很棒,但我们的基础架构上唯一支持的 Java 应用程序服务器是 WebSphere 6.1。这意味着古老的(和已弃用的)JAX-RPC Web 服务框架是我们公开 Web 服务的唯一方式。仅仅在这里进行一个简单的概念验证就是一场噩梦(因为 Java 经验不足,WebSphere 很糟糕,JAX-RPC 很笨重,还有很多 JAR 地狱)。
JAVA EE 5 中的新 JAX-WS 2.0 Web 服务框架看起来很棒——有没有办法在没有整个 Java 应用程序服务器的情况下运行它?例如,在 .Net 的 WCF(Windows 通信框架)中,您几乎可以在任何地方托管服务(进程内、Windows 服务、IIS 6/7 等)。
用一些网络服务包装这个库的最轻量级的方法是什么?
【问题讨论】:
【参考方案1】:是的。
如果您可以创建一个 Java 方法,该方法 1) 使用 @WebMetod 注释,并且 2) 采用所需的参数并调用您的第 3 方代码,并将其包装为 Web 应用程序,您可以使用 Metro 堆栈 - https://metro.dev.java.net/ - 使用任何 Servlet 2.5 Web 容器(将其放在 Web 容器全局 lib 文件夹中)将上述方法公开为 Web 服务。我们使用的是嵌入式 Jetty,但我已经验证这适用于 Tomcat。
我在http://archive.midrange.com/java400-l/200904/msg00071.html 中写下了我的发现
我从https://metro.dev.java.net/1.4/下载了Metro 1.4(1.5版本很新,我还没看),最终解压成几个jar文件。
将 webservices-api.jar、webservices-rt.jar、webservices-extra-api.jar 和 webservices-extra.jar(四个文件)复制到包含所有 tomcat 通用的“祝福”jarfile 的文件夹中 - 我相信它是 $TOMCAT/lib 对于 Tomcat 6。[1]
在您的 Eclipse 项目中最终成为 WAR 文件:
如果您的工作区 JRE 是 Java 5,则必须将 webservices-api.jar 添加到类路径(最终不应部署)。如果是 Java 6 应该可以跳过这一步。
创建一个类 foo.Ping,如下所示:
package foo;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
Ping is a simple web service class providing a "yes, we have contact" class.
Currently the doPing() method provides a response with the host name and
address (if available) and the current server time.
*/
@javax.jws.WebService
public class Ping
@javax.jws.WebMethod(action = "doPing")
public String doPing()
System.out.println("Ping.doPing() called.");
String hostName;
try
hostName = InetAddress.getLocalHost().getHostName();
catch (UnknownHostException e)
hostName = "unknown (" + e.getMessage() + ")";
String hostAddress;
try
hostAddress = InetAddress.getLocalHost().getHostAddress();
catch (UnknownHostException e)
hostAddress = "unknown (" + e.getMessage() + ")";
return "Reached '" + hostName + "' (" + hostAddress + ") at "
+ new java.util.Date() + " java.version="
+ System.getProperty("java.version", "(not set)");
在你的 WEB-INF/web.xml 添加这个 sn-p: com.sun.xml.ws.transport.http.servlet.WSServletContextListener
确保 web.xml 和 sun-jaxws.xml 都包含在部署中!
完成!
现在将您的 war 文件部署到上面准备的 Tomcat 中,并在您部署的 Web 应用程序下打开“/ws”。这可能是http://localhost:8080/foo/ws
;。这将为您提供一个包含所有 Web 服务(包括 Ping)的 WSDL 链接的信息页面。此链接可直接在任何 WSDL 处理工具中使用,包括用于 Java EE 开发人员和 WSDCi 的 Eclipse IDE 中的 Web 服务工具。
希望对你有帮助:)
[1] 不将它们设为全局将会给您带来类加载器问题!
【讨论】:
【参考方案2】:我最终找到了一个比上述任何一个都容易得多的解决方案。我们使用@javax.jws.WebService
和@javax.jws.WebMethod
注释创建了一些简单的类(例如@Thorbjørn Ravn Andersen 的答案中的doPing() 方法),然后使用以下方法部署它们:
string url = "http://localhost:8282/MyService"
MyService serviceInstance = new MyService();
Endpoint svc = Endpoint.publish(url, serviceInstance);
然后我能够将 Visual Studio 指向 http://localhost:8282/MyService?wsdl
并生成一个客户端。很简单。
我们在很长一段时间内通过此服务运行了大量请求,但没有发现任何问题。我们使用 Java Service Wrapper 对其进行了包装,以便它在重新启动/JVM 崩溃等情况下恢复正常。一个穷人的应用程序服务器。
我希望这可以帮助任何其他希望与 Java 进行互操作的 .NET 开发人员,而无需重新映射你的大脑。
【讨论】:
仅作记录。这需要 Java 6,我隐含地假设它不可用,因为你说你唯一的环境是 WebSphere 6.1。很高兴您找到了解决方案!【参考方案3】:关于如何运行其他东西的问题,我不太理解您所说的“我们的基础架构上唯一支持的 Java 应用程序服务器是 WebSphere 6.1”。但是不,您不需要一个完整的 App Server 来公开 Web 服务。
我认为这对你来说是一个很好的起点:http://docs.codehaus.org/display/JETTY/J2se6HttpServerSPI
【讨论】:
换句话说,Glassfish、JBoss 或 WebSphere v7 不是我们的选择。我们的 WebSphere 6.1 配置只支持旧的 JAX-RPC Web 服务,这很麻烦。感谢您提供指向 Jetty 的链接! +1 进一步思考,如果我只是公开 Web 服务,为什么还需要 J2se6HttpServerSPI Jetty 项目? “编写此扩展不仅是为了解决内部 Sun HttpServer 问题 (forums.java.net/jive/message.jspa?messageID=130831),而且还允许紧密集成 JAX-WS Web 服务和 servlet。”可能不是真的需要。但它是一个指向您可以使用的可嵌入 servlet 容器和 JAX-WS 实现的单一链接。我很懒:)【参考方案4】:由于您无法更新您的 JDK 版本,正如我所期望的那样,您与 WebSphere 的需求相关联,因此您可能想尝试一下来自 apache 的 axis famwork。
这将要求您编写一个 Web 服务,该服务仅将调用传递给 java 代码,但它应该为您提供上网工具,并且它适用于旧版本的 java。
我希望 Jax-WS 会成为一个问题,除非您至少使用 JDK5,否则 JAX-WS 会有所帮助,因为注释使开发更像 .NET 2.0 下的 Web 服务模型。
【讨论】:
以上是关于在没有 Java EE 应用服务器的情况下使用 Web 服务在 C# 和 Java 之间进行互操作?的主要内容,如果未能解决你的问题,请参考以下文章