/ / Prečo potrebuje JAXB pre zostavovanie konštruktorov typu "no arg"? - java, xml, jaxb, zoradenie

Prečo potrebuje JAXB pre zoraďovanie žiadny konštruktor? - java, xml, jaxb, zoradenie

Ak sa pokúšate triediť triedu, ktorá odkazuje na komplexný typ, ktorý nemá konštruktor typu no-arg, ako napríklad:

import java.sql.Date;

@XmlRootElement(name = "Foo")
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo {
int i;
Date d; //java.sql.Date does not have a no-arg constructor
}

s implementáciou JAXB, ktorá je súčasťou Java, takto:

    Foo foo = new Foo();
JAXBContext jc = JAXBContext.newInstance(Foo.class);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Marshaller marshaller = jc.createMarshaller();
marshaller.marshal(foo, baos);

JAXB hodí a

com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions java.sql.Date does not have a no-arg default constructor

Teraz chápem, prečo JAXB potrebuje konštruktora typu "no-arg" na unmarshalling - pretože potrebuje objekt inštanktovať. Ale prečo JAXB potrebuje konštruktora typu "no-arg" pri zoraďovaní?

Tiež ďalšie vlákno, prečo Java implementácia JAXB hodí výnimku, ak je pole nulové a nebude taktiež vybavené?

Chýba mi niečo alebo sú to len zlé implementačné voľby v implementácii Java JAXB?

odpovede:

22 pre odpoveď č. 1

Keď JAXB (JSR-222) implementácia inicializuje svoje metadáta, zabezpečuje, že dokáže podporovať zoradenie a zoradenie.

Pre triedy POJO, ktoré nemajú konštruktor typu no-arg, môžete použiť úroveň typu XmlAdapter zaobchádzať s ním:

java.sql.Date nie je predvolene podporovaná (aj keď v EclipseLink JAXB (MOXy) to je). Toto je možné spracovať aj pomocou XmlAdapter špecifikované cez @XmlJavaTypeAdapter na úrovni poľa, majetku alebo balíka:


/>

Tiež ďalšie vlákno, prečo Java implementácia JAXB hodí výnimka, ak je pole nulové a nebude sa zaraďovať vlastne je?

Akú výnimku vidíte? Normálne, keď je pole nulové, nie je zahrnuté do výsledku XML, pokiaľ nie je označené @XmlElement(nillable=true) v takom prípade bude prvok obsahovať xsi:nil="true".


/>

UPDATE

Môžete urobiť nasledovné:

SqlDateAdapter

Nižšie je XmlAdapter ktorý bude konvertovať z java.sql.Date že vaša implementácia JAXB nevie, ako zvládnuť java.util.Date čo robí:

package forum9268074;

import javax.xml.bind.annotation.adapters.*;

public class SqlDateAdapter extends XmlAdapter<java.util.Date, java.sql.Date> {

@Override
public java.util.Date marshal(java.sql.Date sqlDate) throws Exception {
if(null == sqlDate) {
return null;
}
return new java.util.Date(sqlDate.getTime());
}

@Override
public java.sql.Date unmarshal(java.util.Date utilDate) throws Exception {
if(null == utilDate) {
return null;
}
return new java.sql.Date(utilDate.getTime());
}

}

foo

Na XmlAdapter je registrovaná cez @XmlJavaTypeAdapter Anotácia:

package forum9268074;

import java.sql.Date;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement(name = "Foo")
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo {
int i;

@XmlJavaTypeAdapter(SqlDateAdapter.class)
Date d; //java.sql.Date does not have a no-arg constructor
}

0 pre odpoveď č. 2

Zdá sa, pod dojmom, že JAXB introspekcie kód bude mať akciu osobitné chodníky pre inicializáciu.Ak áno, ktorý by mať za následok veľa duplicitné kód a bude zlá implementácia.Já bych si predstaviť, že JAXB kód má bežné rutinné, ktorý skúma model triedy prvýkrát je potrebná a overuje, že takto všetky potrebné dohovorov.v tejto situácii, je to inak, pretože jedným z členov nemá požadované č-arg konštruktor.Inicializácia logika nie je s najväčšou pravdepodobnosťou marshall/vyradiť špecifické a tiež vysoko nepravdepodobné, že brať do úvahy aktuálnu inštanciu objektu.


-2 pre odpoveď č. 3

Niektoré podnikové a Závislosť injekcie rámce používajú reflexie Class.newInstance() Ak chcete vytvoriť novú inštanciu vašej triedy. Táto metóda vyžaduje verejné č-arg konštruktéra byť schopní vytvoriť inštanciu objektu.