不使用Java EE应用服务器,如何使用Web服务在C#和Java之间进行互操作?

3

我处于困境之中: 我们有一个第三方企业系统,该系统提供基于Java的API。然而,我们是一个100%的.Net开发团队。实际上,我需要使用一些东西来包装Java API,以便C#代码可以调用。

网络服务可能很好,但我们基础设施上支持的唯一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 Communication Framework)中,你可以将服务托管在几乎任何地方(进程内、Windows服务、IIS 6/7等)。

最轻量级的方法是什么,可以将此库与一些Web服务包装起来?

4个回答

2

可以。

如果您可以创建一个Java方法,该方法1)带有@WebMetod注释,2)需要参数并调用您的第三方代码,并将其封装为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“祝福”的jar文件的文件夹中 - 我相信对于Tomcat 6.[1],它是$ {TOMCAT} / lib。

在最终成为WAR文件的Eclipse项目中:

  • 如果您的工作区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中添加以下代码片段:
    <listener>
    <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
    </listener>
    <servlet>
    <description>JAX-WS 端点 - 此servlet必须处理所有端点</description>
    <display-name>webservice</display-name>
    <servlet-name>webservice</servlet-name>
    <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
    </servlet>
<!-- 每个端点都必须映射到JAX-WS端点servlet -->
<servlet-mapping> <servlet-name>webservice</servlet-name> <url-pattern>/ws</url-pattern> </servlet-mapping>
创建一个新文件 WEB-INF/sun-jaxws.xml:
    <endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime' version='2.0'>
        <endpoint name='ping' implementation='foo.Ping'url-pattern='/ws'>
        </endpoint
    </endpoints>
确保将web.xml和sun-jaxws.xml都包含在部署中!
完成!
现在将你的war文件部署到上面准备好的Tomcat,并在你部署的web应用程序下打开“/ws”。这可能是 http://localhost:8080/foo/ws。 这将为您提供包括所有Web服务(包括Ping)WSDL的信息页面的链接。此链接可直接用于任何WSDL处理工具,包括Eclipse IDE for Java EE Developers和WSDCi中的Web服务工具。
希望这能帮到你 :)
[1]不将它们设置为全局变量会导致类加载器问题!

1
我最终找到了一种比上述任何方法都要简单的解决方案。我们创建了一些简单的类(例如@Thorbjørn Ravn Andersen答案中的doPing()方法),并使用@javax.jws.WebService和@javax.jws.WebMethod注释部署它们:
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。很高兴你找到了解决方案! - Thorbjørn Ravn Andersen

1
我不太理解你的说法:“我们基础设施上唯一支持的Java应用服务器是WebSphere 6.1”,与如何运行其他东西的问题有关。但是,不,你不需要一个完整的应用服务器来公开Web服务。
我认为这是你的一个很好的起点:http://docs.codehaus.org/display/JETTY/J2se6HttpServerSPI

换句话说,Glassfish、JBoss或WebSphere v7对我们来说并不是选项。我们的WebSphere 6.1配置仅支持旧版本的JAX-RPC Web服务,这非常麻烦。感谢提供Jetty的链接!+1 - intoOrbit
进一步思考,如果我只是暴露 Web 服务,那么为什么需要 J2se6HttpServerSPI Jetty 项目呢? - intoOrbit
这个扩展不仅是为了解决内部Sun HttpServer问题(http://forums.java.net/jive/message.jspa?messageID=130831),还允许JAX-WS Web服务和servlet的紧密集成。也许并不是必需的,但它是一个指向可嵌入的servlet容器和JAX-WS实现的单一链接,您可以使用它。我有点懒 :) - ykaganovich

0

由于您无法更新JDK版本,我想您可能受到WebSphere的限制,您可以尝试使用来自Apache的axis框架。

这将要求您编写一个Web服务,只需将调用传递给Java代码即可,但它应该为您提供在线工具,并且与旧版本的Java兼容。

我认为,除非您至少使用JDK5,否则Jax-WS将是一个问题,然而如果使用JAX-WS,则注释使开发更像.NET 2.0下的Web服务模型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接