# Anlaufprobleme mit SOAP



## Reyneke (2. Dez 2009)

Servus.

Ich soll ein Anmeldesystem für Studenten mit SOAP entwickeln. Bisher lief es ganz gut, doch nun treffe ich auf zwei Probleme, denn die anwedung soll in der lage sein ein Array von Studenten zu empfangen und es dann auszugeben, sowie einzelne Studenten zu suchen. Beides klappt leider noch nicht und ich finde den Fehler nicht, irgendwie.

Hier der Quellcode, was ich bisher habe (Das Ganze wird mittels Swing und AWT programmiert)


```
private void seekStudentActionPerformed(java.awt.event.ActionEvent evt) {                                            
        // TODO add your handling code here:
        try { // Call Web Service Operation
            bhtvs2.AnmeldeServer service = new bhtvs2.AnmeldeServer();
            bhtvs2.AnmeldeServerPortType port = service.getAnmeldeServer();
            // TODO initialize WS operation arguments here
            java.lang.String id = "";
            javax.xml.ws.Holder<java.lang.String> name = new javax.xml.ws.Holder<java.lang.String>();
            javax.xml.ws.Holder<java.lang.String> matrikelNummer = new javax.xml.ws.Holder<java.lang.String>();
            javax.xml.ws.Holder<byte[]> image = new javax.xml.ws.Holder<byte[]>();
            javax.xml.ws.Holder<Integer> group = new javax.xml.ws.Holder<Integer>();
            javax.xml.ws.Holder<Integer> status = new javax.xml.ws.Holder<Integer>();
            port.getStudent(id, name, matrikelNummer, image, group, status);
            System.out.println("Test: " + name);
        } catch (Exception ex) {
            // TODO handle custom exceptions here
            ex.printStackTrace();
        }

    }                                           

    private void showAllActionPerformed(java.awt.event.ActionEvent evt) {                                        
        // TODO add your handling code here:
        try { // Call Web Service Operation
            bhtvs2.AnmeldeServer service = new bhtvs2.AnmeldeServer();
            bhtvs2.AnmeldeServerPortType port = service.getAnmeldeServer();
            // TODO process result here
            bhtvs2.ArrayOfnsStudent result = port.listStudents();
            //bhtvs2.
            System.out.println("Result = " + result.getAny().size());
            System.out.println("Result = " + result.getArrayType().toString());
            System.out.println("Result = " + result.getClass());
            System.out.println("Result = " + result);
        } catch (Exception ex) {
            // TODO handle custom exceptions here
            ex.printStackTrace();
        }
```

Edit: Die Klasse ArrayOfnsStudent ist folgendermaßen definiert:

```
public class ArrayOfnsStudent extends Array

Java class for ArrayOfns__Student complex type.
The following schema fragment specifies the expected content contained within this class.
 <complexType name="ArrayOfns__Student">
   <complexContent>
     <restriction base="{http://schemas.xmlsoap.org/soap/encoding/}Array">
       <attribute ref="{http://schemas.xmlsoap.org/soap/encoding/}arrayType"/>
     </restriction>
   </complexContent>
 </complexType>
```


Und hier der Quellcode des dazugehörigen WSDL Files.


```
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="anmeldeServer"
 targetNamespace="urn:bhtvs2"
 xmlns:tns="urn:bhtvs2"
 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
 xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 xmlns:ns="urn:bhtvs2"
 xmlns:SOAP="http://schemas.xmlsoap.org/wsdl/soap/"
 xmlns:MIME="http://schemas.xmlsoap.org/wsdl/mime/"
 xmlns:DIME="http://schemas.xmlsoap.org/ws/2002/04/dime/wsdl/"
 xmlns:WSDL="http://schemas.xmlsoap.org/wsdl/"
 xmlns="http://schemas.xmlsoap.org/wsdl/">

<types>

 <schema targetNamespace="urn:bhtvs2"
  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:ns="urn:bhtvs2"
  xmlns="http://www.w3.org/2001/XMLSchema"
  elementFormDefault="unqualified"
  attributeFormDefault="unqualified">
  <import namespace="http://schemas.xmlsoap.org/soap/encoding/" schemaLocation="http://schemas.xmlsoap.org/soap/encoding/"/>

  <complexType name="ArrayOfns__Student">
   <complexContent>
    <restriction base="SOAP-ENC:Array">
     <attribute ref="SOAP-ENC:arrayType" WSDL:arrayType="ns:Student[]"/>
    </restriction>
   </complexContent>
  </complexType>

<complexType name="Student">
<sequence>
 <element name="name" type="string"/>
 <element name="matrikelNummer" type="string"/>
 <element name="image" type="xsd:base64Binary"/>
 <element name="group" type="xsd:int"/>
 <element name="status" type="int"/>
</sequence>
</complexType>

 </schema>

</types>

<message name="getVersionRequest"/>

<message name="getVersionResponse">
 <part name="result" type="xsd:string"/>
</message>

<message name="addStudentRequest">
 <part name="student" type="ns:Student"/>
</message>

<message name="addStudentResponse">
 <part name="result" type="xsd:int"/>
</message>

<message name="getStudent">
 <part name="id" type="xsd:string"/>
</message>

<message name="Student">
 <part name="name" type="xsd:string"/>
 <part name="matrikelNummer" type="xsd:string"/>
 <part name="image" type="xsd:base64Binary"/>
 <part name="group" type="xsd:int"/>
 <part name="status" type="xsd:int"/>
</message>

<message name="listStudentsRequest"/>
<message name="listStudentsResponse">
 <part name="result" type="ns:ArrayOfns__Student"/>
</message>

<portType name="anmeldeServerPortType">
 <operation name="getVersion">
  <documentation>returns the <i>version</i> as string like 00.01.01</documentation>
  <input message="tns:getVersionRequest"/>
  <output message="tns:getVersionResponse"/>
 </operation>
 <operation name="addStudent">
  <documentation>adds student to one of two groups (1,2) and returns a <i>Status</i> 1,2 or -1 if failed.</documentation>
  <input message="tns:addStudentRequest"/>
  <output message="tns:addStudentResponse"/>
 </operation>
 <operation name="getStudent">
  <documentation>Service definition of function ns__getStudent</documentation>
  <input message="tns:getStudent"/>
  <output message="tns:Student"/>
 </operation>
 <operation name="listStudents">
  <documentation>Service definition of function ns__listStudents</documentation>
  <input message="tns:listStudentsRequest"/>
  <output message="tns:listStudentsResponse"/>
 </operation>
</portType>

<binding name="anmeldeServer" type="tns:anmeldeServerPortType">
 <SOAP:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
 <operation name="getVersion">
  <SOAP:operation style="rpc" soapAction=""/>
  <input>
     <SOAP:body use="encoded" namespace="urn:bhtvs2" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
  </input>
  <output>
     <SOAP:body use="encoded" namespace="urn:bhtvs2" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
  </output>
 </operation>
 <operation name="addStudent">
  <SOAP:operation style="rpc" soapAction=""/>
  <input>
     <SOAP:body use="encoded" namespace="urn:bhtvs2" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
  </input>
  <output>
     <SOAP:body use="encoded" namespace="urn:bhtvs2" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
  </output>
 </operation>
 <operation name="getStudent">
  <SOAP:operation style="rpc" soapAction=""/>
  <input>
     <SOAP:body use="encoded" namespace="urn:bhtvs2" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
  </input>
  <output>
     <SOAP:body use="encoded" namespace="urn:bhtvs2" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
  </output>
 </operation>
 <operation name="listStudents">
  <SOAP:operation style="rpc" soapAction=""/>
  <input>
     <SOAP:body use="encoded" namespace="urn:bhtvs2" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
  </input>
  <output>
     <SOAP:body use="encoded" namespace="urn:bhtvs2" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
  </output>
 </operation>
</binding>

<service name="anmeldeServer">
 <documentation>fuer BHT VS2 Studenten </documentation>
 <port name="anmeldeServer" binding="tns:anmeldeServer">
  <SOAP:address location="http://www.jnks.de:80"/>
 </port>
</service>

</definitions>
```


----------



## Reyneke (2. Dez 2009)

Soo, ich habe den Quellcode etwas angepasst und das hier ist das Ergebnis:


```
private void showAllActionPerformed(java.awt.event.ActionEvent evt) {                                        
        // TODO add your handling code here:
        try { // Call Web Service Operation
            bhtvs2.AnmeldeServer service = new bhtvs2.AnmeldeServer();
            bhtvs2.AnmeldeServerPortType port = service.getAnmeldeServer();
            // TODO process result here
            bhtvs2.ArrayOfnsStudent result = port.listStudents();
            bhtvs2.Student[] student = new bhtvs2.Student[result.getAny().size()];
            student = result.getAny().toArray(student);
            //bhtvs2.
            System.out.println("Result = " + result.getAny().size());
            System.out.println("Result = " + result.getArrayType().toString());
            System.out.println("Result = " + result.getClass());
            System.out.println("Result = " + result);
            
            for(int count=0; count<result.getAny().size() ;count++) {
                //System.out.println("Result = " + result.getAny().getClass());
                System.out.println("Student: " + student[count].getName());
            }
        } catch (Exception ex) {
            // TODO handle custom exceptions here
            ex.printStackTrace();
        }

    }
```

Die mir, leider, folgende Exception liefert:


```
java.lang.ArrayStoreException
        at java.lang.System.arraycopy(Native Method)
        at java.util.ArrayList.toArray(ArrayList.java:306)
        at anmeldesystemclient.WorkingWindow.showAllActionPerformed(WorkingWindow.java:320)
        at anmeldesystemclient.WorkingWindow.access$400(WorkingWindow.java:27)
        at anmeldesystemclient.WorkingWindow$5.actionPerformed(WorkingWindow.java:120)
        at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
        at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
        at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
        at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
        at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
        at java.awt.Component.processMouseEvent(Component.java:6216)
        at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
        at java.awt.Component.processEvent(Component.java:5981)
        at java.awt.Container.processEvent(Container.java:2041)
        at java.awt.Component.dispatchEventImpl(Component.java:4583)
        at java.awt.Container.dispatchEventImpl(Container.java:2099)
        at java.awt.Component.dispatchEvent(Component.java:4413)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4556)
        at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4220)
        at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4150)
        at java.awt.Container.dispatchEventImpl(Container.java:2085)
        at java.awt.Window.dispatchEventImpl(Window.java:2475)
        at java.awt.Component.dispatchEvent(Component.java:4413)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
```

Woran könnte das liegen?


----------



## maki (2. Dez 2009)

Die Exception deutet an, dass du versuchst unterschiedliche Arrays ineinander zu kopieren.


```
bhtvs2.ArrayOfnsStudent result = port.listStudents();
            bhtvs2.Student[] student = new bhtvs2.Student[result.getAny().size()];
            student = result.getAny().toArray(student);
```
Was genau liefert denn [c]result.getAny()[/c]?
Jedenfalls nicht [c]bhtvs2.Student[][/c], vielleicht [c]Object[][/c]?


----------



## Reyneke (2. Dez 2009)

Also wenn ich mir das Ergebnis von result.getAny() ausgeben lasse bekomme ichfolgendes:

```
Result = [[item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null], [item: null]]
```

Jedoch wenn ich angebe result.getAny().getClass() erhalte ich "ArrayList".

Als Notation steht bei getAny() :


```
org.​xmlsoap.​schemas.​soap.​encoding.​Array
public List<Object> getAny()
Gets the value of the any property.
This accessor method returns a reference to the live list, not a snapshot. Therefore any modification you make to the returned list will be present inside the JAXB object. This is why there is not a set method for the any property.
For example, to add a new item, do as follows:
    getAny().add(newItem);
 
Objects of the following type(s) are allowed in the list Element Object
```


----------



## maki (2. Dez 2009)

Du versucht ein  [c]Object[][/c] in ein [c]bhtvs2.Student[][/c] zu kopieren, das geht nicht.


----------



## Reyneke (2. Dez 2009)

Hmmmm - und wie könnte ichs dann besser lösen? Zumal er aus dem übergebenen bhtvs2.ArrayOfnsStudent eigentlich Studentendaten auslesen sollte. Hast du da einen guten Tipp? Evtl. das Ganze zuerst in ein Objectarray legen?


----------



## maki (2. Dez 2009)

> Evtl. das Ganze zuerst in ein Objectarray legen?


Ja


----------



## Reyneke (2. Dez 2009)

Mhmmm, aber was wird dann aus den Informationen die ich zurückbekomme? Weil eigentlich soillten in bhtvs2.ArrayOfnsStudent Studenteninformationen liegen, die zuvor in einer Datenbank eingetragen wurden. Es gibt eine Klasse Student von der bhtvs2.ArrayOfnsStudent eigentlich ein Array sein sollte. Wie kann ich diese Informationen retten?

In C# sieht die obenstehende Lösung in etwa so aus: Student[] student = port.listStudents(); - und kann dann natürlich einfach mit einem Arraybefehl abgefragt werden. Doch ich schreibe leider net in C# *seufzt*


----------



## Reyneke (2. Dez 2009)

Hmmm. Ich hab den Quellcode jetzt angepasst, aber nun beomme ich eine OutofBound Exception.


```
try { // Call Web Service Operation
            bhtvs2.AnmeldeServer service = new bhtvs2.AnmeldeServer();
            bhtvs2.AnmeldeServerPortType port = service.getAnmeldeServer();
            // TODO process result here
            bhtvs2.ArrayOfnsStudent result = port.listStudents();
            bhtvs2.Student[] student = new bhtvs2.Student[result.getAny().size()];
            Object[] oStudent = result.getAny().toArray();
            for(int count = 0; count < oStudent.length; ++count) {
                student[count] = (bhtvs2.Student) oStudent[count];
            }
            //student = result.getAny().toArray(student);
            //bhtvs2.Student[]
            //student = (bhtvs2.Student[])result.getAny().toArray(student);
            System.out.println("Result = " + result.getAny().size());
            System.out.println("Result = " + result.getArrayType().toString());
            System.out.println("Result = " + result.getClass());
            System.out.println("Result = " + result);
            for(int count = 0; count < student.length; count++) {
                //System.out.println("Result = " + result.getAny().getClass());
                System.out.println("Student: " + student[count].getName());
                //System.out.println("Student: " + oStudent[count].toString());
            }
        } catch (Exception ex) {
            // TODO handle custom exceptions here
            ex.printStackTrace();
        }
```


----------



## Reyneke (3. Dez 2009)

Nach einigem Herumrätseln, bin ich auf dieses Ergebnis gekommen:


```
private void showAllActionPerformed(java.awt.event.ActionEvent evt) {                                        
        // TODO add your handling code here:
        try { // Call Web Service Operation
            bhtvs2.AnmeldeServer service = new bhtvs2.AnmeldeServer();
            bhtvs2.AnmeldeServerPortType port = service.getAnmeldeServer();
            // TODO process result here
            bhtvs2.ArrayOfnsStudent result = port.listStudents();
            bhtvs2.Student[] student = new bhtvs2.Student[result.getAny().size()];
            Object[] oStudent = result.getAny().toArray();
            for(int count = 0; count < oStudent.length; ++count) {
                System.out.println("oStudentlength: " + oStudent.length);
                student[count] = (bhtvs2.Student) oStudent[count];
            }
            //student = result.getAny().toArray(student);
            //bhtvs2.Student[]
            //student = (bhtvs2.Student[])result.getAny().toArray(student);
            System.out.println("Result = " + result.getAny().isEmpty());
            System.out.println("Result = " + result.getAny().size());
            System.out.println("Result = " + result.getArrayType().toString());
            System.out.println("Result = " + result.getClass());
            System.out.println("Result = " + result);
            for(int count = 0; count < student.length; count++) {
                //System.out.println("Result = " + result.getAny().getClass());
                System.out.println("Student: " + student[count].getName());
                //System.out.println("Student: " + oStudent[count].toString());
            }
        } catch (Exception ex) {
            // TODO handle custom exceptions here
            ex.printStackTrace();
        }
    }
```

Interessanterweise werden die Beiden Schleifen nicht abgearbeitet, da das Ergebnis stets 0 ist und auch result.getAny().getsize eine null liefert (result.getAny().isEmpty() liefert true) - ich hab das Laufzeitergebnis mal hier hineingepostet und bin, wieder mal, ratlos.


```
Result = true
Result = 0
Result = ns1:Student[0]
Result = class bhtvs2.ArrayOfnsStudent
Result = bhtvs2.ArrayOfnsStudent@ff8c74
```


----------



## Reyneke (3. Dez 2009)

Hmmm, offenbar habe ich das Problem bis dato von der falschen Seite gesehen. Bei exakter Nachfrage, bekam ich zurück, daß 
	
	
	
	





```
bhtvs2.ArrayOfnsStudent result = port.listStudents();
```
 einem nur eine Liste der Studenten liefert, sprich: Einen String. Nur warum erhalte ich dann bei der Ausgabe nur 
	
	
	
	





```
bhtvs2.ArrayOfnsStudent@ff8c74
```
 ?


----------



## maki (3. Dez 2009)

> inem nur eine Liste der Studenten liefert, sprich: Einen String. Nur warum erhalte ich dann bei der Ausgabe nur


Weil anscheinend die toString Methode nur die Typinfo + @ + Hashwert liefert, so wie in Object


----------



## OvG (4. Dez 2009)

Das Problem scheint das Mapping des DataTransferObjects zu sein, er kann auf den Typ nicht mappen. Warum? Keine Ahnung, ist schon spät.

Helfen könnte eventuell:
http://www.java-forum.org/soa/85756-elementnsimpl-result-jax-ws-soap-client.html und 
java.net Forums : JAX-WS web service return ElementNSImpl ...

Da es scheinbar schnell gehen muss, hier eine andere Lösung:

Ich hab mal die Client Stub generierung in Netbeans von JAX-WS Style auf JAX-RPC Style umgestellt und damit läufts.

Hier die nun modifizierte Methode:

```
public static void main(String[] args) {
        try { // Call Web Service Operation
            javaapplication1.AnmeldeServer service = new javaapplication1.AnmeldeServer_Impl();
            javaapplication1.AnmeldeServerPortType port = service.getAnmeldeServer();
            // TODO process result here
            javaapplication1.Student[] result = port.listStudents();

            System.out.println(port.getVersion());
            System.out.println(result.length);

            for(int i = 0; i<result.length; i++){
                javaapplication1.Student lStudent = result[i];
                System.out.println("Name: "+ lStudent.getName() + "Matr.Nr.: " + lStudent.getMatrikelNummer());
            }
        } catch (Exception ex) {
            // TODO handle custom exceptions here
            ex.printStackTrace();
        }
    }
```

Output ist nun wie erwartet.


----------



## Reyneke (4. Dez 2009)

OKay. Problem ERLEDIGT. *seufzt* Wieder mal ein 1d10T Fehler meinerseits ...

Danke an alle, die geholfen haben  Vor allem an OvG der sich mit mir bis in den frühen Morgen hinein zusmmengesetzt hat.

Einfache Frage. Gibt es ein gutes Tutorial, wie man einen Filedialog erstellt? In meinem Fall benötige ich es für das hochladen der Bilder. Und über einen guten Tipp zur Konvertierung Icon -> Image, Image -> Icon und ByteArray -> Image wäre ich sehr begeistert  Respektive über einen guten Link zu einem Tutorial darüber.

Bis dann
- Reyneke


----------

