开发者

How do I send an array or collection of complex objects using web services in Java (e.g. Axis2)?

开发者 https://www.devze.com 2023-02-17 11:36 出处:网络
I\'m relatively new to SOAP/web services; while I\'ve done a few smaller web services projects I\'ve incidentally never needed to return (or use as a parameter) an array or collection of \'complex\' o

I'm relatively new to SOAP/web services; while I've done a few smaller web services projects I've incidentally never needed to return (or use as a parameter) an array or collection of 'complex' objects. When I attempt to do so, I get varying odd behaviour depending on my SOAP binding style.

When I use RPC/literal, I can send and receive arrays of built-in types (e.g. String[]), but when I try a 'complex' object, I get marshaling errors (e.g. xyz nor any of its super class is known to this context), despite having added the relevant classes to the @XmlSeeAlso annotation.

Alternatively, trying Document/literal/wrapped (which seems to be best practice?) allows me to send or receive complex objects, but results in some oddities when I try to pass around arrays of any type. For example, String[] t = { "A", "B", "C", "D" }; reaches the web service as a an empty String (not String[]).

Does anyone have any idea what's going on here or how to get things working in any sensible way? I'm deploying locally to Apache Geronimo at the moment.

Server code snippet:

Interface:

@WebService
@SOAPBinding(style=Style.DOCUMENT, use=Use.LITERAL, parameterStyle=ParameterStyle.WRAPPED) 
@XmlSeeAlso({Feedback.class,Feedback[].class})
public interface CerberusRequest {

...

    @WebMethod
    public Feedback[] test(String[] facts) throws Exception;

}

Implementation:

@WebService(serviceName = "CerberusRequestService", portName
    = "CerberusRequestPort", targetNamespace = "http://web.cerberus.xyz.gov/",
    endpointInterface = "gov.xyz.cerberus.web.CerberusRequest")
public class CerberusRequestImpl implements CerberusRequest {
    ...
    public Feedback[]开发者_如何转开发 test(String[] facts) throws Exception {
        //Just some debug crap (prints: "in test...1 [Ljava.lang.String;")
        System.out.println("in test..." + facts.length + " " + facts.getClass().getName());
        for(String f : facts) {
            System.out.println("test:" + f);
        }
        //return feedback;
        Feedback[] f = { new Feedback() };
        return f;
    }
}

Client code snippet:

URL url = new URL(destination+"?wsdl");
QName qname = new QName(namespace, service);

Service service = Service.create(url, qname);
CerberusRequest sr = service.getPort(CerberusRequest.class);

String[] t = { "A", "B", "C", "D" };
Feedback[] feedback = sr.test(t);
for(Feedback f : feedback) {
    System.out.println(f);
}

WSDL:

<?xml version="1.0" encoding="utf-8"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://web.cerberus.xyz.gov/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="CerberusRequestService" targetNamespace="http://web.cerberus.xyz.gov/">
  <types>
    <xsd:schema>
      <xsd:import namespace="http://web.cerberus.xyz.gov/" schemaLocation="http://localhost:8080/CerberusService/CerberusRequest?xsd=xsd1"/>
    </xsd:schema>
    <xsd:schema>
      <xsd:import namespace="http://jaxb.dev.java.net/array" schemaLocation="http://localhost:8080/CerberusService/CerberusRequest?xsd=xsd2"/>
    </xsd:schema>
  </types>

  <message name="Exception">
    <part element="tns:Exception" name="fault">
    </part>
  </message>
  <message name="test">
    <part element="tns:test" name="parameters">
    </part>
  </message>
  <message name="testResponse">

    <part element="tns:testResponse" name="parameters">
    </part>
  </message>
  <portType name="CerberusRequest">
    <operation name="test">
      <input message="tns:test">
    </input>
      <output message="tns:testResponse">
    </output>

      <fault message="tns:Exception" name="Exception">
    </fault>
    </operation>
  </portType>
  <binding name="CerberusRequestPortBinding" type="tns:CerberusRequest">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <operation name="test">
      <soap:operation soapAction=""/>
      <input>

        <soap:body use="literal"/>
      </input>
      <output>
        <soap:body use="literal"/>
      </output>
      <fault name="Exception">
        <soap:fault name="Exception" use="literal"/>
      </fault>
    </operation>

  </binding>
  <service name="CerberusRequestService">
    <port binding="tns:CerberusRequestPortBinding" name="CerberusRequestPort">
      <soap:address location="http://localhost:8080/CerberusService/CerberusRequest"/>
    </port>
  </service>
</definitions>

Thank you very much in advance for any and all help you can provide!


Well I had similar kind of issues I wanted to pass the VO , which had a complex object (map) inside and this map could contain map of maps as values or List of Map.

Even if you support the current requirement you may end up in other issues later. Better you can use third party serializers like Castor/Dozer/GSon kind of tools. And change the data a simple java type which can be easily passed over the wire.

0

精彩评论

暂无评论...
验证码 换一张
取 消