2012-03-12 11 views
5

Jestem wściekły z usług internetowych.Wywoływanie usługi powracającej do mydła z obiektów z klienta java z osią

Mam bardzo prosty usługa soap:

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

I

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

I

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

wdrożyć usługę pod GlassFish 3.1.

Używanie konsoli glassfish działa.

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

Używanie php działa również (dla obu metod).

Teraz z klientem 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])); 
    } 
} 

Pierwsze połączenie działa, ale nie drugi.

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) 

Co mogę zrobić?

Po wielu godzin szukając w internecie i próbują differents rozwiązania nadal nic nie pracuje ...

Czy istnieje proste rozwiązanie?

Dzięki.

Edit:

próbował także, że:

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

Z tego wyniku:

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

Czy uczeń implementuje Serializable? –

+0

Tak - zobacz mój zredagowany wpis. – tweetysat

+0

Spróbuj zalogować wiadomość. Zgodnie z komunikatem o błędzie jest błędne: napotkano element potomny, który NIE jest oczekiwany – jddsantaella

Odpowiedz

3

pierwszy element odpowiedzi przy użyciu klienta mydła.

Problem pochodzi z przestrzeni nazw maptypes: nie ma nazw

Więc teraz mam

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

a także dodać

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

do klasy Student mieć

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

Klient oś:

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

Nadanie wszystkie uczniów:

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

Klient oś2:

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

Nadanie

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

Ale nie wiem jak deserializować omelement.

Próbowałem z

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

ale daje mi

Student [matricule=null, name=null] 

Jak mogę to zrobić?

Leaving problemy:

  • nie wiem jak zrobić to samo z osią --OK Patrz przed -/oś 2
  • do 'resp' (klient) zawiera mydło tylko pierwszy Student
+0

Nie wiem jak deserializować omelement - patrz edytowane reposnse. – tweetysat

0

Whats styl wiązania SOAP używasz, RPC/DOKUMENT? Jeśli używasz RPC, wówczas żądanie i odpowiedź zostaną zakodowane i przetworzone, Axis2 nie obsługuje wiadomości w formacie kodowanym RPC. Spróbuj użyć stylu wiązania DOCUMENT SOAP. (Powinienem umieścić to w komentarzach, uprzejmie znieść)

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

+0

Dzięki. Próbowałem dodać @SOAPBinding (style = Style.DOCUMENT, parameterStyle = ParameterStyle.WRAPPED) Zarówno AxisClient i SoapClient nie działają. Ten sam wyjątek. Ale używam osi, a nie osi2. – tweetysat

2

nie możesz dostać się do czegoś WSDL jak

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

, a następnie użyć osi wsdl2java, aby Axis mógł utworzyć dla ciebie kod klienta (który będzie miał wszystkie poprawne odwzorowania typów i przestrzenie nazw)?

+0

Dzięki. Nie użyłem twojego rozwiązania, ale teraz działa mój klient osi. – tweetysat

Powiązane problemy