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ď č. 1Keď 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:
- http://blog.bdoughan.com/2011/05/jaxb-and-joda-time-dates-and-times.html
- http://blog.bdoughan.com/2011/01/jaxb-and-datetime-properties.html
/>
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.