【问题标题】:Return custom object from Web services using JAX-WS使用 JAX-WS 从 Web 服务返回自定义对象
【发布时间】:2023-03-11 06:19:01
【问题描述】:

问题有点长,但我想提前提供所有信息

我有以下课程:

package test.api.soap.server;

public class TestClassA {

    public TestClassA() {

    }

    public String doA() {
        System.out.println("Start doA()");
        return "In do A";
    }
}

我想将它公开为 Web 服务,但不是直接公开,所以我创建了包装类: 打包 test.api.soap.server;

import javax.jws.WebMethod;
import javax.jws.WebService;

@WebService
public class MyClientApiV2_5 {

    public MyClientApiV2_5() {

    }

    @WebMethod
    public TestClassA getTestClassA() {
        return new TestClassA();
    }
}

我在 ant 任务中使用标准 wsgen 创建服务器 WSDL:

<target name="Create-JAXWS-SOAP-Server">
    <echo message="Generate SOAP server stubs" />
    <exec executable="${wsgen-cmd}">
        <arg value="-verbose" />
        <arg value="-classpath" />
        <arg value="${build}" />
        <arg value="-wsdl" />
        <arg value="-d" />
        <arg value="${build}" />
        <arg value="-r" />
        <arg value="wsdl" />
        <arg value="-s" />
        <arg value="${src}" />
        <arg value="-keep" />
        <arg value="test.api.soap.server.MyClientApiV2_5" />
    </exec>
</target> 

结果是 2 个文件: MyClientApiV25Service.wsdl

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.2.3-b01-. -->
<definitions targetNamespace="http://server.soap.api.test/" name="MyClientApiV2_5Service" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:tns="http://server.soap.api.test/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
  <types>
    <xsd:schema>
      <xsd:import namespace="http://server.soap.api.test/" schemaLocation="MyClientApiV25Service_schema1.xsd"/>
    </xsd:schema>
  </types>
  <message name="getTestClassA">
    <part name="parameters" element="tns:getTestClassA"/>
  </message>
  <message name="getTestClassAResponse">
    <part name="parameters" element="tns:getTestClassAResponse"/>
  </message>
  <portType name="MyClientApiV2_5">
    <operation name="getTestClassA">
      <input wsam:Action="http://server.soap.api.test/MyClientApiV2_5/getTestClassARequest" message="tns:getTestClassA"/>
      <output wsam:Action="http://server.soap.api.test/MyClientApiV2_5/getTestClassAResponse" message="tns:getTestClassAResponse"/>
    </operation>
  </portType>
  <binding name="MyClientApiV2_5PortBinding" type="tns:MyClientApiV2_5">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
    <operation name="getTestClassA">
      <soap:operation soapAction=""/>
      <input>
        <soap:body use="literal"/>
      </input>
      <output>
        <soap:body use="literal"/>
      </output>
    </operation>
  </binding>
  <service name="MyClientApiV2_5Service">
    <port name="MyClientApiV2_5Port" binding="tns:MyClientApiV2_5PortBinding">
      <soap:address location="REPLACE_WITH_ACTUAL_URL"/>
    </port>
  </service>
</definitions>

MyClientApiV25Service_schema1.xsd

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" targetNamespace="http://server.soap.api.test/" xmlns:tns="http://server.soap.api.test/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="getTestClassA" type="tns:getTestClassA"/>
  <xs:element name="getTestClassAResponse" type="tns:getTestClassAResponse"/>
  <xs:complexType name="getTestClassA">
    <xs:sequence/>
  </xs:complexType>
  <xs:complexType name="getTestClassAResponse">
    <xs:sequence>
      <xs:element name="return" type="tns:testClassA" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="testClassA">
    <xs:sequence/>
  </xs:complexType>
</xs:schema>

我创建了客户端存根:

<target name="Create-JAXWS-SOAP-Client" >
    <echo message="Generate SOAP client stubs" />
    <exec executable="${wsimport-cmd}">
        <arg value="-verbose" />
        <arg value="-keep" />
        <arg value="-s" />
        <arg value="${src}" />
        <arg value="-d" />
        <arg value="${build}" />
        <arg value="-p" />
        <arg value="test.api.soap.client.stubs" />
        <arg value="wsdl\MyClientApiV25Service.wsdl" />
    </exec>
</target> 

然后我编写简单的客户端类来获取 Web 服务:

package test.api.soap.client;

import java.net.MalformedURLException;
import java.net.URL;

import javax.xml.namespace.QName;

import test.api.soap.client.stubs.MyClientApiV25;
import test.api.soap.client.stubs.MyClientApiV25Service;
import test.api.soap.client.stubs.TestClassA;

public class SampleClient {

    private MyClientApiV25         api         = null;
    static MyClientApiV25Service service;

    public SampleClient() throws MalformedURLException {
        api = service.getMyClientApiV25Port();

        TestClassA testClass = api.getTestClassA();
        testClass.doA();
    }
}

问题是: 编写 testClass.doA();返回:

没有为类型TestClassA定义方法doA()

有什么建议吗?

【问题讨论】:

  • 看起来您正试图使 TestClassA 成为像 RMI 中的“远程”对象。这不是 jaxws 的工作方式(或一般的 web 服务)。从 jax-ws 服务调用返回的对象是简单的 DTO。
  • 感谢您的回答。您知道在 Web 服务中执行此操作的好方法吗?我希望 MyClientApiV2_5 将成为不同 API 的入口点。我不想在一个类中暴露所有的方法,也不想有多个入口。
  • 我认为没有办法在 jax-ws 中“链接”服务。您基本上需要对单独的服务有单独的入口点。您可以拥有一个顶级“服务”,它具有返回字符串的方法,这些字符串是其他子服务的 url。

标签: java web-services soap wsdl jax-ws


【解决方案1】:

添加@XmlRootElement 注释。然后 JaxB 将处理您的复杂类型的编组/解组。默认情况下,公共字段会自动绑定,但您也可以使用@XmlElement 自己注释它们。

package test.api.soap.server;

@XmlRootElement
public class TestClassA {

    public TestClassA() {

    }

    public String doA() {
        System.out.println("Start doA()");
        return "In do A";
    }
}

【讨论】:

  • 谢谢,我明天去看看
  • 谢谢,我知道我需要改变方法。
猜你喜欢
  • 2012-12-16
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
  • 2016-07-30
  • 2013-02-26
  • 2023-04-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多