2016-03-22 13 views
9

Ich baue eine Reihe von verknüpften Klassen, deren Instanzen ich in XML marshall werden soll, damit ich sie in einer Datei speichern und später wieder einlesen kann.Marshalling LocalDate mit JAXB

Derzeit Ich verwende den folgenden Code als Testfall:

import javax.xml.bind.annotation.*; 

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.JAXBException; 
import javax.xml.bind.Marshaller; 

import java.time.LocalDate; 

public class LocalDateExample 
{ 
    @XmlRootElement 
    private static class WrapperTest { 
    public LocalDate startDate; 
    } 

    public static void main(String[] args) throws JAXBException 
    { 
    WrapperTest wt = new WrapperTest(); 
    LocalDate ld = LocalDate.of(2016, 3, 1); 
    wt.startDate = ld; 
    marshall(wt); 
    } 

    public static void marshall(Object jaxbObject) throws JAXBException 
    { 
    JAXBContext context = JAXBContext.newInstance(jaxbObject.getClass()); 
    Marshaller marshaller = context.createMarshaller(); 
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); 
    marshaller.marshal(jaxbObject, System.out); 
    } 
} 

Die XML-Ausgabe ist:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<wrapperTest> 
    <startDate/> 
</wrapperTest> 

Gibt es einen Grund, warum die startDate Element leer ist? Ich möchte, dass es die Zeichenfolgendarstellung des Datums enthält (d. H. toString()). Muss ich etwas eigenen Code schreiben, um dies zu tun?

Die Ausgabe von java -version ist:

openjdk version "1.8.0_66-internal" 
OpenJDK Runtime Environment (build 1.8.0_66-internal-b17) 
OpenJDK 64-Bit Server VM (build 25.66-b17, mixed mode) 

Antwort

13

Sie eine XmlAdapter wie diese erstellen haben:

public class LocalDateAdapter extends XmlAdapter<String, LocalDate> { 
    public LocalDate unmarshal(String v) throws Exception { 
     return LocalDate.parse(v); 
    } 

    public String marshal(LocalDate v) throws Exception { 
     return v.toString(); 
    } 
} 

und mit Anmerkungen versehen Feld mit

@XmlJavaTypeAdapter(value = LocalDateAdapter.class) 

Siehe auch javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters wenn Sie möchten Ihre Adapter auf einer Paketebene definieren.

+0

scheint genau das zu tun, was ich will - danke! – pwaring

2

http://blog.bdoughan.com/2011/05/jaxb-and-joda-time-dates-and-times.html beschreibt das Loch Setup.

Joda-Time bietet eine Alternative zu den derzeit in Java SE verfügbaren Klassen für Datum und Kalender. Da sie in einer separaten Bibliothek bereitgestellt werden, stellt JAXB keine Standardzuordnung für diese Klassen bereit.

Um den Adapter für alle Dateien in einem Paket zu registrieren. Sie können package-info.java in dem Paket hinzufügen, das Sie registrieren möchten.

@XmlJavaTypeAdapters({ 
    @XmlJavaTypeAdapter(type=LocalDate.class, 
     value=LocalDateAdapter.class), 
}) 
package PACKAGE_NAME; 

import java.time.LocalDate; 
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters; 

Der Adapter wie folgt aussieht:

import javax.xml.bind.annotation.adapters.XmlAdapter; 
import java.time.LocalDate; 

public class LocalDateAdapter extends XmlAdapter<String, LocalDate>{ 

    public LocalDate unmarshal(String v) throws Exception { 
     return LocalDate.parse(v); 
    } 

    public String marshal(LocalDate v) throws Exception { 
     return v.toString(); 
    } 

} 
+0

Ich benutze Joda Time nicht, ich benutze die 'java.time. *' Klassen (die ähnlich zu sein scheinen, aber Teil von Java 8 sind und deshalb nicht als Abhängigkeit spezifiziert werden müssen). – pwaring

+0

Sie haben Recht. Ich habe nur eine alte Lösung von mir benutzt, um deine zu testen. Ich werde meine Antwort aktualisieren –

+0

Danke, die andere Antwort war ein wenig prägnanter, also habe ich das als akzeptiert markiert. – pwaring

Verwandte Themen