2012-03-12 15 views
5

Mi sto arrabbiando con i servizi web.Richiamare soap webservice che restituisce l'elenco di oggetti dal client java con l'asse

ho una molto semplice webservice sapone:

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

E

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

E

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

schiero il servizio in GlassFish 3.1.

Utilizzo della console glassfish, funziona.

<?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> 

Utilizzo di php funziona anche (per entrambi i metodi).

Ora, con 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])); 
    } 
} 

La prima chiamata è in funzione ma non il secondo.

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) 

Cosa posso fare?

Dopo molte ore alla ricerca su internet e cercando soluzioni differenti ancora niente lavoro ...

C'è una soluzione semplice?

Grazie.

Edit:

provato inoltre che:

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()); 
    } 
} 

Con questo risultato:

Caught SOAPException (SOAP-ENV:Client): No Deserializer found to deserialize a ':return' using encoding style 'http://schemas.xmlsoap.org/soap/encoding/'. 
+0

Lo Studente implementa Serializable? –

+0

Sì - guarda il mio post modificato. – tweetysat

+0

Prova a registrare il messaggio. Secondo il messaggio di errore, il messaggio è errato: si è verificato un elemento figlio, che NON è previsto – jddsantaella

risposta

3

Primo elemento di risposta utilizzando client SOAP.

Il problema è in arrivo dallo spazio nome maptypes: non c'è spazio dei nomi

Così ora, ho

smr.mapTypes(Constants.NS_URI_SOAP_ENC,new QName("","student"),Student.class, null, new BeanSerializer()); 
    smr.mapTypes(Constants.NS_URI_SOAP_ENC,new QName("","matricule"),Integer.class, null, new IntDeserializer()); 
    smr.mapTypes(Constants.NS_URI_SOAP_ENC,new QName("","name"),Integer.class, null, new StringDeserializer()); 

e anche aggiungere

@XmlRootElement(name = "Student",namespace="http://services.tuto.java.com/") 

alla classe degli studenti di avere

<?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/"> 
      <student> 
       <matricule>1236</matricule> 
       <name>student1</name> 
      </student> 
      <student> 
       <matricule>5678</matricule> 
       <name>student2</name> 
      </student> 
     </ns2:getStudentsResponse> 
    </S:Body> 
</S:Envelope> 

Il cliente assi:

public class AxisClient 
{ 
    public static void main(String[] args) throws Exception 
    { 
    String endPoint = "http://localhost:8080/StudentServiceImplService/StudentServiceImpl"; 
    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")); 
    call2.setReturnType(new QName("","student"), Student.class); 
    call2.setReturnType(new QName("", "student")); 
    call2.registerTypeMapping(Student.class, new QName("", "student"), null,new BeanDeserializerFactory(Student.class, new QName("", "student"))); 
    List<Student> students = (List<Student>) call2.invoke(new Object[0]); 
    for (Student student : students) 
    { 
     System.out.println(student); 
    } 
    } 
} 

Dare tutti studenti:

Student [matricule=1236, name=student1] 
Student [matricule=5678, name=student2] 

Il cliente axis2:

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

    ServiceClient sc = new ServiceClient(); 

    Options opts = new Options(); 
    opts.setTo(new EndpointReference("http://localhost:8080/StudentServiceImplService/StudentServiceImpl")); 
    sc.setOptions(opts); 

    OMFactory fac = OMAbstractFactory.getOMFactory(); 
    OMNamespace omNs = fac.createOMNamespace("http://services.tuto.java.com/","ns1"); 

    OMElement method = fac.createOMElement("getStudents", omNs); 
    OMElement res = sc.sendReceive(method); 
    System.out.println(res); 

    Iterator<OMElement> it = res.getChildElements(); 
    while(it.hasNext()) 
    { 
     System.out.println(it.next()); 
    } 
} 

Dare

<ns2:getStudentsResponse xmlns:ns2="http://services.tuto.java.com/"><student><matricule>1236</matricule><name>student1</name></student><student><matricule>5678</matricule><name>student2</name></student></ns2:getStudentsResponse> 
<student><matricule>1236</matricule><name>student1</name></student> 
<student><matricule>5678</matricule><name>student2</name></student> 

Ma non so come deserializzare l'omelement.

ho provato con

Student student = (Student) BeanUtil.deserialize(Student.class,res,new DefaultObjectSupplier(),null); 

ma mi

Student [matricule=null, name=null] 

dà Come posso fare?

problemi Partenza:

  • non so come fare lo stesso con l'asse --OK vedere prima -/asse 2
  • il 'resp' (client SOAP) contiene solo primo studente
+0

Non so come deserializzare l'omelement - vedi reposnse modificato. – tweetysat

0

Che cosa è lo stile di rilegatura SOAP che si sta utilizzando, RPC/DOCUMENTO? Se si utilizza RPC, la richiesta e la risposta verranno codificate ed elaborate, Axis2 non supporta i messaggi in formato codificato RPC. Prova a utilizzare lo stile di associazione SOAP DOCUMENT. (Avrei dovuto mettere questo nei commenti, vi preghiamo di orso)

consultare https://stackoverflow.com/a/9598193/752129

+0

Grazie. Ho provato ad aggiungere @SOAPBinding (style = Style.DOCUMENT, parameterStyle = ParameterStyle.WRAPPED) Sia AxisClient che SoapClient non funzionano. Stessa eccezione Ma sto usando l'asse e non l'asse2. – tweetysat

2

si fa a non arrivare al WSDL qualcosa come

http://localhost:8080/StudentServiceImplService/StudentServiceImpl?wsdl 

e quindi utilizzare l'asse wsdl2java per consentire a Axis di creare il codice client per l'utente (che avrà tutti i mapping di tipi e spazi dei nomi corretti)?

+0

Grazie. Non ho usato la tua soluzione ma ora il mio client assi sta funzionando. – tweetysat

Problemi correlati