Invoquer webservice soap retour liste des objets à partir de java client avec l'axe

Je deviens fou avec des webservices.

J'ai une question très simple webservice soap :

@Remote
public interface StudentService
{
public String sayHello();
public List<Student> getStudents();
}

Et

@Stateless
@WebService
public class StudentServiceImpl implements StudentService
{

@Override
public String sayHello()
{
    return "Hello World";
}

public List<Student> getStudents()
{
    List<Student> students = new ArrayList<Student>();

    Student st1 = new Student();
    st1.setMatricule(1234);
    st1.setName("student1");
    students.add(st1);

    Student st2 = new Student();
    st2.setMatricule(5678);
    st2.setName("student2");
    students.add(st2);

    return students;
    }
}

Et

public class Student implements Serializable
{
private static final long serialVersionUID = 8286393242028201686L;

private int matricule; 
private String name;

public int getMatricule()
{
    return matricule;
}
public void setMatricule(int matricule)
{
    this.matricule = matricule;
}

public String getName()
{
    return name;
}
public void setName(String name)
{
    this.name = name;
}
}

Je déployer le service sous glassfish 3.1.

À l'aide de la glassfish console, ça marche.

<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body>
        <ns2:getStudentsResponse xmlns:ns2="http://services.tuto.java.com/">
            <return>
                <matricule>1234</matricule>
                <name>student1</name>
            </return>
            <return>
                <matricule>5678</matricule>
                <name>student2</name>
            </return>
        </ns2:getStudentsResponse>
    </S:Body>
</S:Envelope>

À l'aide de php, c'est aussi de travail (pour les deux méthodes).

Maintenant avec un client java :

import javax.xml.namespace.QName;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;

public class Client
{
public static void main(String[] args) throws Exception
{
    String endPoint = "http://localhost:8080/StudentServiceImplService/StudentServiceImpl";

    Service service = new Service();
    Call call = (Call) service.createCall();
    call.setTargetEndpointAddress(new java.net.URL(endPoint));
    call.setOperationName(new QName("http://services.tuto.java.com/","sayHello"));

    System.out.println(call.invoke(new Object[0]));

    Service service2 = new Service();
    Call call2 = (Call) service2.createCall();
    call2.setTargetEndpointAddress(new java.net.URL(endPoint));
    call2.setOperationName(new QName("http://services.tuto.java.com/","getStudents"));

    System.out.println(call2.invoke(new Object[0]));
    }
}

Le premier appel est un travail, mais pas la seconde.

Hello World
12-mars-2012 14:53:23 org.apache.axis.client.Call invoke
GRAVE: Exception:
org.xml.sax.SAXException: SimpleDeserializer encountered a child element, which is NOT expected, in something it was trying to deserialize.
at org.apache.axis.encoding.ser.SimpleDeserializer.onStartChild(SimpleDeserializer.java:145)
at org.apache.axis.encoding.DeserializationContext.startElement(DeserializationContext.java:1035)
at org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java:165)
at org.apache.axis.message.MessageElement.publishToHandler(MessageElement.java:1141)
at org.apache.axis.message.RPCElement.deserialize(RPCElement.java:345)
at org.apache.axis.message.RPCElement.getParams(RPCElement.java:384)
at org.apache.axis.client.Call.invoke(Call.java:2467)
at org.apache.axis.client.Call.invoke(Call.java:2366)
at org.apache.axis.client.Call.invoke(Call.java:1812)
at Client.main(Client.java:24)

Que puis-je faire ?

Après plusieurs heures de recherche sur internet et d'essayer différentes solutions toujours rien ...

Est-il une solution simple ?

Grâce.

Edit :

Aussi essayé :

public class SoapClient
{
public static void main(String[] args) throws Exception
{
SOAPMappingRegistry smr = new SOAPMappingRegistry();
BeanSerializer beanSer = new BeanSerializer();
smr.mapTypes(Constants.NS_URI_SOAP_ENC,new QName("http://services.tuto.java.com/", "StudentServiceImplService"),Student.class, beanSer, beanSer);       
Call call = new Call();
call.setSOAPMappingRegistry(smr);
call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
call.setTargetObjectURI("http://services.tuto.java.com/");
call.setMethodName("getStudents");
Response resp;
try
{
resp = call.invoke(new URL("http://8h9l45j:8080/StudentServiceImplService/StudentServiceImpl"), "");
}
catch (SOAPException e)
{
System.err.println("Caught SOAPException (" +
e.getFaultCode() + "): " + e.getMessage());
return;
}
if (!resp.generatedFault())
{
Parameter ret = resp.getReturnValue();
Object value = ret.getValue();
if ( value != null )
{
String[] tlist = (String[])value;
System.out.println();
for ( int i = 0; i < tlist.length; i++ )
System.out.println(tlist[i]);
}
}
else
{
Fault fault = resp.getFault();
System.err.println("Generated fault: ");
System.out.println ("  Fault Code   = "
+ fault.getFaultCode());
System.out.println ("  Fault String = "
+ fault.getFaultString());
}
}

Avec ce résultat :

Caught SOAPException (SOAP-ENV:Client): No Deserializer found to deserialize a ':return' using encoding style 'http://schemas.xmlsoap.org/soap/encoding/'.
N'Étudiant Sérialisable?
Oui, consultez édité mon post.
Essayez de vous connecter le message. Selon le message d'erreur message est faux: rencontré un élément enfant, qui n'est PAS prévu
Ok, je comprends maintenant le sens de la ':return' -- Voir édité question pour le message, j'ai essayé avec un Retour de la classe avec le matricule et le nom des propriétés, des getters et setters. Et modifier cette ligne : smr.mapTypes(Constantes.NS_URI_SOAP_ENC,new QName("services.tuto.java.com", "retour"),Return.class, beanSer, beanSer); Mais toujours pas de travail, même exception.
Comment puis-je faire pour le changer dans ma réponse dans le message soap <retour> <étudiant> ?

OriginalL'auteur tweetysat | 2012-03-12