Как отправить массив или набор сложных объектов с помощью веб-сервисов на Java (например, Axis2)?

Я относительно новичок в SOAP/веб-сервисах; в то время как я сделал несколько небольших проектов веб-сервисов, мне никогда не приходилось возвращать (или использовать в качестве параметра) массив или набор «сложных» объектов. Когда я пытаюсь это сделать, я получаю разное странное поведение в зависимости от моего стиля привязки SOAP.

Когда я использую RPC/literal, я могу отправлять и получать массивы встроенных типов (например, String[]), но когда я пробую «сложный» объект, я получаю ошибки маршалинга (например, xyz или любой из его суперклассов известен в этом контексте), несмотря на добавление соответствующих классов в аннотацию @XmlSeeAlso.

В качестве альтернативы, попытка Document/literal/wrapped (что кажется лучшей практикой?) позволяет мне отправлять или получать сложные объекты, но приводит к некоторым странностям, когда я пытаюсь передать массивы любого типа. Например, String[] t = { "A", "B", "C", "D" }; достигает веб-службы как пустая String (не String[]).

Кто-нибудь знает, что здесь происходит или как заставить все работать разумным образом? В данный момент я выполняю локальное развертывание в Apache Geronimo.

Фрагмент кода сервера:

Интерфейс:

@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;

}

Реализация:

@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;
    }
}

Фрагмент кода клиента:

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>

Заранее большое спасибо за любую помощь, которую вы можете оказать!


person Chris    schedule 15.03.2011    source источник


Ответы (1)


Ну, у меня были похожие проблемы, я хотел передать VO, внутри которого был сложный объект (карта), и эта карта могла содержать карту карт в качестве значений или список карт.

Даже если вы поддерживаете текущее требование, позже вы можете столкнуться с другими проблемами. Лучше вы можете использовать сторонние сериализаторы, такие как инструменты Castor/Dozer/GSon. И измените данные простым типом Java, который можно легко передать по сети.

person java_enthu    schedule 13.08.2011