gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 09:24:31 25 4
gpt4 key购买 nike

我在两个独立的应用程序服务器上有两个 Java EE 应用程序。其中之一已经包含一个工作的 EJB。我希望能够通过使用 JAX-WS web 服务从其他应用程序与此 EJB 进行通信(通信必须在不同的应用程序服务器和不同的服务器版本之间进行,因此远程 EJB 调用是不可取的)。将服务器api暴露给客户端应用程序是没有问题的。服务器端很清楚,添加@Webservice注解似乎效果很好。但我想知道构建客户端的最佳方法是什么:我真的不想从 wsdl 生成客户端 stub (在我的例子中它本身是由容器从 ejb 代码生成的)并打包所有这些生成的类进入客户耳中 - 但这似乎是我可以使用 @WebServiceRef 注释的唯一方法。

规范不推荐借助 javax.xml.ws.Service 的静态方法(例如 service=Service.create() 和 service.getPort())自己制作动态代理的替代方法和“容器提供者不需要支持使用这些方法创建的托管服务实例”。但这就是……。我想使用:

有没有办法在我的代码中注入(inject)一个由应用程序服务器管理的动态代理?还是通过生成的客户端 stub 类来获取托管 Web 服务客户端实例的唯一方法?

最佳答案

阅读 JAX-WS 2.2 规范,第 4 章:客户端 API。

<强>1。静态客户端生成

确实是使用 JAX-WS 的最简单方法。从 Web 服务的角度来看,WSDL 是接口(interface)和连接属性。即使您选择不实际使用它,您仍然需要从逻辑上了解它才能进行有意义的 SOAP 调用。

JAX-WS 规范注释:使用 SOAP 1.1/HTTP 绑定(bind)的端点必须在以 ?WSDL 为后缀的发布地址使其契约(Contract)作为 WSDL 1.1 文档可用。或 ?wsdl

<强>2。动态客户端编程

Is there a way to get a dynamic proxy injected in my code, managed by the application server?

此方法涉及针对 JAX-WS API 的动态编程,以使用或不使用 WSDL 连接到 Web 服务。没有办法凭空“注入(inject)”动态代理。您需要使用 SEI 的端口 URL 构建和配置一个。 WSDL 文档是存储此类配置信息的标准位置,尽管可以避免它并以编程方式插入信息。

  • 2A) 使用 WSDL 进行动态编程:

     javax.xml.ws.Service service = Service.create(
    new URL("http://example.org/stocks.wsdl"),
    new QName("http://example.org/stocks", "StockQuoteService"));
    com.example.StockQuoteProvider proxy = service.getPort(portName,
    com.example.StockQuoteProvider.class)
    javax.xml.ws.BindingProvider bp = (javax.xml.ws.BindingProvider)proxy;
    Map<String,Object> context = bp.getRequestContext();
    context.setProperty("javax.xml.ws.session.maintain", Boolean.TRUE);
    proxy.getLastTradePrice("ACME");

    相对于 (1) 的优点:可以在部署应用后动态更改 WSDL 文档,提供此类更改不会影响到客户端的 java 接口(interface)。

    即对您没有什么好处。您的 WSDL 是静态的。虽然您可以将您的客户端指向<service endpoint URL>?wsdl动态查找,这意味着你需要手动配置<service endpoint URL>在不影响您的客户端逻辑的情况下,几乎没有其他可以在 SEI/WSDL 中更改的内容。

  • 2B) 没有 WSDL 的动态编程:

    String endpointUrl = ...;           
    QName serviceName = new QName("http://example.org/wssample/echo/", "EchoService");
    QName portName = new QName("http://example.org/wssample/echo/", "EchoServicePort");

    /** Create a service and add at least one port to it. **/
    Service service = Service.create(serviceName);
    service.addPort(portName, SOAPBinding.SOAP11HTTP_BINDING, endpointUrl);

    /** Create a Dispatch instance from a service.**/
    Dispatch<SOAPMessage> dispatch = service.createDispatch(portName,
    SOAPMessage.class, Service.Mode.MESSAGE);

    /** Create SOAPMessage request. **/
    // compose a request message
    MessageFactory mf = MessageFactory.newInstance(SOAPConstants.SOAP_1_1_PROTOCOL);

    // Create a message. This example works with the SOAPPART.
    SOAPMessage request = mf.createMessage();
    SOAPPart part = request.getSOAPPart();

    // Obtain the SOAPEnvelope and header and body elements.
    SOAPEnvelope env = part.getEnvelope();
    SOAPHeader header = env.getHeader();
    SOAPBody body = env.getBody();

    // Construct the message payload.
    SOAPElement operation = body.addChildElement("invoke", "ns1",
    "http://com/ibm/was/wssample/echo/");
    SOAPElement value = operation.addChildElement("arg0");
    value.addTextNode("ping");
    request.saveChanges();

    /** Invoke the service endpoint. **/
    SOAPMessage response = dispatch.invoke(request);

    优点(不是真的):最终可以让它执行与上述相同的行为。

    缺点:编程复杂。非标准配置(在 WSDL 之外)。需要避免硬编码设置。易受界面变化影响。在服务器和客户端之间手动同步设置 - 容易遗漏某些东西,极难调试。

回答:

回到(1)。从 WSDL 生成客户端 stub 。将它用作接口(interface)契约——它应该设计得很好并且不能更改。

然后用节省下来的时间解决实际问题... ;) ;)

关于java - Java EE 应用程序之间的 Web 服务通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15663023/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com