# XML mit JAXB und Annotations aufbauen klappt nicht wie gewollt



## iTob86 (15. Jul 2016)

Hallo zusammen,

zunächst als kleine Info: Ich schwimme gerade von meiner langjährigen .NET Insel zur Java Insel rüber (und es gibt doch so einige starke Wellen dabei) ;-)

Ich benötige einige Hilfe zu dem o.g. Thema (Sorry schonmal, falls für euch seltsam klingende Fragen kommen könnten)

Ausgangslage: 
- Ich habe eine genaue Vorgabe für ein XML mit folgender Struktur. 
- Diese Vorgabe ist bis auf 1 fehlende Sache umgesetzt -> Es fehlt das "xsi:type" Attribut


```
<a xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <b>
    <c xsi:type="type1" id="1281">
      <d>
        ...
      </d>
    </c>
  </b>
</a>
```

Was habe ich bereits?
- Einen JAR-RS Webservice mit Maven aufgesetzt
- Mehrere Models mit Annotationen erstellt (Die jeweiligen Elemente sind ein eigenes Model).

Wie kann ich das realisieren mit dem xsi-type Attribut?
In .NET ging das ganze mit Polymorphie aus der OOP Welt und dem Attribut "XmlInclude", jedoch komme ich in Java nicht weiter.

Danke schonmal...


----------



## stg (15. Jul 2016)

Zeig doch einfach mal deinen bisherigen Code, der den fehlerhaften Output erzeugt.


----------



## iTob86 (15. Jul 2016)

Hallo stg,

Meine Models:

```
@XmlRootElement(name = "a")
public class a {
         
    @XmlAttribute
    public boolean AdditionalJobsPending;

    @XmlElement(name = "jobList")
//  @XmlElementRef
    public b JobList = new b();
}


public class b
{
    @XmlAttribute(name = "jobListId")
    public int ID;

    @XmlElement(name = "job") 
    public ArrayList<c> job = new ArrayList();
}


@XmlRootElement
public abstract class c
{
    @XmlAttribute(name = "id")
    public int ID;  

    private String Envelope;

    public void setEnvelope(String Envelope) {
        this.Envelope = Envelope;
    }

    public String getEnvelope() {
        return Envelope;
    }
}


@XmlRootElement(name = "d")
public class d extends c 
{
}
```

Logikcode:


```
@GET    
@Produces(MediaType.APPLICATION_XML)
public Response GetJobList() throws Exception 
{    
    Response restResponse= Response.status(200).entity("").build();
     
    a aresult = new a();
    aresult.JobList.ID = "123";

    try
    {                        
        d djob = new d();
        djob.ID = "987";
        djob.setEnvelope("<envelope></envelope>");
   
        // Hier Polymorphie
        aresult.JobList.job.add(d);
    }
    catch (SAXParseException err) 
    {
        System.out.println ("** Parsing error" + ", line " + err.getLineNumber () + ", uri " + err.getSystemId ());
        System.out.println(" " + err.getMessage ());

    }catch (SAXException e) 
    {
        Exception x = e.getException ();
        ((x == null) ? e : x).printStackTrace ();
    }
    catch (Throwable t) 
    {
        t.printStackTrace ();
    }
           
    restResponse = Response.status(200).entity(aresult).build();
   
    return restResponse;
}
```

Läuft es evtl auf Marshalling hinaus?

Gruß,
iTob


----------



## Flown (15. Jul 2016)

Vielleicht hilft dir das weiter: http://stackoverflow.com/questions/20679163/xsitype-and-xmlnsxsi-in-generated-xml-by-jaxb


----------



## iTob86 (16. Jul 2016)

Hi Flown,
danke für den Tipp.

Ich habe es entsprechend angepasst, jedoch bekomme ich nun ein HTTP 500. Die Glassfish logs haben keine näheren Infos dazu. Wo kann ich mehr zum 500er erfahren? 
Um zu sehen was serialisiert wird habe ich es durch den jaxb marshaller gejagt und ausgeben lassen:


```
<a>
    <b jobListId="356">
        <c xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="type1">
            <envelope></envelope>
        </c>
    </b>
</a>
```

Hat er beim Return bzw. serialisieren ein Problem wegen dem xmlns Attribut, weil es nicht im root ist?


----------



## iTob86 (18. Jul 2016)

Gelöst: Als ReturnType Response nehmen und als Entity den Output vom Marshaller als String anhängen.


```
JAXBContext jc = JAXBContext.newInstance(a.class, b.class, c.class);              
java.io.StringWriter sw = new StringWriter();              
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(result, sw);             
restResponse = Response.status(200).entity(sw.toString()).build();
```


----------

