在没有 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.WSServletContextListenerJAX-WS 端点 - 此 servlet 必须处理所有端点webservicewebservicecom.sun.xml.ws.transport.http.servlet.WSServlet1webservice/ws 创建一个新文件 WEB-INF/sun-jaxws.xml: 端点 端点>

确保 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 之间进行互操作?的主要内容,如果未能解决你的问题,请参考以下文章

登录后重定向错误(Java EE w/JSF)

Java - 在没有磁盘的情况下处理内存中的文件 R/W

Java EE 应用程序之间的 Web 服务通信

在 JAVA ee 中使用 JWT 保护 REST 服务

为什么Java EE计时器没有集群?

java 事务