在没有 Java EE 应用服务器的情况下使用 Web 服务在 C# 和 Java 之间进行互操作?

发布于 2024-08-10 13:11:31 字数 502 浏览 3 评论 0原文

我的处境很困难:我们有一个公开基于 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 等)。

用一些 Web 服务包装这个库的最轻量级方法是什么?

I'm in a difficult position: We have a 3rd party enterprise system that exposes a Java-based API. However, we are a 100% .Net oriented development team. Essentially, I need to wrap the Java API with something that C# code can call.

Web services would be great, but the only Java application server supported on our infrastructure is WebSphere 6.1. This means the ancient (and deprecated) JAX-RPC web service framework is the only way for us to expose web services. Just getting a simple proof-of-concept working here has been a nightmare (because of Java inexperience, WebSphere being awful, JAX-RPC being clunky, and lots of JAR hell).

The new JAX-WS 2.0 web service framework in JAVA EE 5 looks great-- is there any way to run this without an entire Java application server? For example, in .Net's WCF (Windows Communication Framework), you can host services pretty much anywhere you want (in-process, Windows Service, IIS 6/7 etc).

What is the most lightweight way to wrap this library with some web services?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

眼眸里的快感 2024-08-17 13:11:31

是的。

如果您可以创建一个 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 下载了 Metro 1.4 .java.net/1.4/(1.5版本很新,我还没看过),它最终解压成几个jar文件。

将 webservices-api.jar、webservices-rt.jar、webservices-extra-api.jar 和 webservices-extra.jar(四个文件)复制到包含所有 tomcat 通用的“blessed”jarfiles 的文件夹中 - 我相信它是 ${ 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 中添加以下代码段:
    <listener>
    <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
    </listener>
    <servlet>
    <description>JAX-WS endpoint - this servlet must handle all endpoints</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>

    <!-- each endpoint must have a mapping to the JAX-WS endpoint 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] 不使它们全局化会给您带来类加载器问题!

Yes.

If you can create a Java method which is 1) annotated with @WebMetod and 2) takes the needed parameters and call into your 3'rd party code, and wrap it up as a web application you can use the Metro stack - https://metro.dev.java.net/ - with any Servlet 2.5 web container (put it in the web containers global lib folder) to expose the above method as a web service. We are using an embedded Jetty, but I've verified this works with Tomcat.

I wrote up my findings in http://archive.midrange.com/java400-l/200904/msg00071.html


I downloaded Metro 1.4 from https://metro.dev.java.net/1.4/ (version 1.5 is very new and I haven't looked at it), which eventually unpacks to several jar files.

Copy webservices-api.jar, webservices-rt.jar, webservices-extra-api.jar and webservices-extra.jar (four files) to the folder containing "blessed" jarfiles common to all of tomcat - I believe it is ${TOMCAT}/lib for Tomcat 6.[1]

In your Eclipse project eventually ending up to be a WAR file:

  • If your workspace JRE is Java 5, you must add webservices-api.jar to the classpath (it should not be deployed in the end). If it is Java 6 you should be able to skip this step.

  • Create a class foo.Ping looking like:


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)");
  }
}

  • In your WEB-INF/web.xml add this snippet:
    <listener>
    <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
    </listener>
    <servlet>
    <description>JAX-WS endpoint - this servlet must handle all endpoints</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>

    <!-- each endpoint must have a mapping to the JAX-WS endpoint servlet -->

    <servlet-mapping>
    <servlet-name>webservice</servlet-name>
    <url-pattern>/ws</url-pattern>
    </servlet-mapping>
  • Create a NEW file 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>
  • Ensure that both web.xml and sun-jaxws.xml are included in the deployment!

  • Done!

Now deploy your war file to the Tomcat prepared above, and open "/ws" under your deployed web application. This might be http://localhost:8080/foo/ws;. This will give you a page with information including a link to WSDL for all web services, including the Ping. This link can be used directly in any WSDL processing tool, including the web service tool in Eclipse IDE for Java EE Developers and WSDCi.

Hope this helps you :)

[1] Not making them global WILL give you classloader problems!

帅冕 2024-08-17 13:11:31

关于如何运行其他东西的问题,我不太明白您的说法“我们的基础设施上支持的唯一 Java 应用程序服务器是 WebSphere 6.1”。但不,您不需要一个完整的应用程序服务器来公开 Web 服务。

我认为这对您来说是一个很好的起点: http://docs.codehaus.org/display /JETTY/J2se6HttpServerSPI

I don't quite understand your statement "the only Java application server supported on our infrastructure is WebSphere 6.1" with respect to the question about how to run other stuff. But no, you don't need a full App Server just to expose a web service.

I think this is a good starting point for you: http://docs.codehaus.org/display/JETTY/J2se6HttpServerSPI

冷…雨湿花 2024-08-17 13:11:31

我最终找到了一个比上述任何一个都容易得多的解决方案。我们使用 @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 开发人员,而无需重新思考即可做到这一点。

I ended up finding a solution that was far easier than any of the above. We created some simple classes (like the doPing() method in @Thorbjørn Ravn Andersen's answer) with the @javax.jws.WebService and @javax.jws.WebMethod annotations, then deployed them using:

string url = "http://localhost:8282/MyService"
MyService serviceInstance = new MyService();
Endpoint svc = Endpoint.publish(url, serviceInstance);

I was then able to point Visual Studio at http://localhost:8282/MyService?wsdl and generate a client. Easy as pie.

We have run a lot of requests through this service over a large span of time and have not noticed any problems. We wrapped this with the Java Service Wrapper so that it comes back up across reboots/JVM crashes, etc. A poor man's application server.

I hope this might help any other .NET developer looking to interoperate with Java without having to remap your brain to do it.

压抑⊿情绪 2024-08-17 13:11:31

由于您无法更新您的 JDK 版本,正如我所期望的那样,您与 WebSphere 的需求紧密相关,因此您可能需要考虑尝试来自 apache 的 axis Famework。

这需要您编写一个仅传递对 java 代码的调用的 Web 服务,但它应该为您提供上网工具,并且它可以与旧版本的 java 配合良好。

我预计 Jax-WS 会成为一个问题,除非奇迹般地你至少使用 JDK5,然后 JAX-WS 会很有帮助,因为注释使开发更像 .NET 2.0 下的 Web 服务模型。

Since you can't update your version of the JDK, as I expect you are tied to what WebSphere needs, you may want to look at trying the axis famework, from apache.

This would require you to write a webservice that would just pass calls to the java code, but it should provide you the tools to get online, and it works well with older versions of java.

I expect that Jax-WS would be a problem unless by some miracle you are on JDK5 at least, then JAX-WS would be helpful, as the annotations makes the development more like the webservice model under .NET 2.0.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文