Reputation: 1303
I am currently trying the JAXB library for XML to POJO conversion. I have a class which as follows :
class Student {
String name;
Integer id;
Date dateOfBirth;
@XmlJavaTypeAdapter(TimeDateAdapter.class)
Timestamp admitTime;
//constructor and getter setters
}
Now I want to input these fields via XML. So I reproduce xml something like :
<student>
<name>Student 1</name>
<id>123</id>
<dob>29-02-1991</dob>
<admitTime>231441321413</admitTime>
</student>
So, as you might know it will throw an error saying it cannot convert Timestamp since there is no no-arg constructor in Timestamp class. So I will have to create an Adapter. So, I was wondering if there is a way of creating a generic adapter for Date, timestamp and maybe Calendar as well so that they can be unmarshalled and marshalled according to the implementation?
EDIT: I created an Adapter for marshalling and unmarshalling my java.sql.Timestamp object from and to xml. Here is the code :
import java.sql.Timestamp;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class TimeDateAdapter extends XmlAdapter<String, Timestamp>{
@Override
public String marshal(Timestamp v) throws Exception {
return v.toString();
}
@Override
public Timestamp unmarshal(String v) throws Exception {
return new Timestamp(Long.parseLong(v));
}
}
Its giving me the following error :
Exception in thread "main" com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 3 counts of IllegalAnnotationExceptions
There are two properties named "publishDate"
this problem is related to the following location:
at public java.sql.Timestamp Book.getPublishDate()
at Book
this problem is related to the following location:
at private java.sql.Timestamp Book.publishDate
at Book
java.sql.Timestamp does not have a no-arg default constructor.
this problem is related to the following location:
at java.sql.Timestamp
at public java.sql.Timestamp Book.getPublishDate()
at Book
Class has two properties of the same name "publishDate"
this problem is related to the following location:
at public java.sql.Timestamp Book.getPublishDate()
at Book
this problem is related to the following location:
at private java.sql.Timestamp Book.publishDate
at Book
at com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:102)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:472)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:302)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1140)
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:154)
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:121)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:248)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:235)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:432)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:637)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:584)
at BookMain.main(BookMain.java:42)
Upvotes: 2
Views: 7045
Reputation:
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class TimestampAdapter extends XmlAdapter<String, Timestamp> {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH.mm.ss.SSSSSS");
@Override
public Timestamp unmarshal(String value) throws Exception {
return Timestamp.valueOf(LocalDateTime.parse(value, formatter));
}
@Override
public String marshal(Timestamp timestamp) throws Exception {
return timestamp.toLocalDateTime().format(formatter);
}
}
Upvotes: 0
Reputation: 149017
JAXB (JSR-222) implementations support java.util.Date
and java.util.Calendar
by default so you will not require an XmlAdapter
for them. Classes like java.sql.Date
, java.sql.Time
, and java.sql.Timestamp
will require an XmlAdapter
. I would recommend separate adapters instead of trying to combine them into one.
Note
An XmlAdapter
can be specified at the package level. When doe this way it applies to all mapped fields/properties on that type belonging to domain classes in that package. This can greatly reduce the amount of times you need to specify @XmlJavaTypeAdapter
. You can read more about this approach on my blog.
There are two properties named "publishDate"
this problem is related to the following location:
at public java.sql.Timestamp Book.getPublishDate()
at Book
this problem is related to the following location:
at private java.sql.Timestamp Book.publishDate
at Book
By default JAXB treats public properties (get/set method pairs) and annotated fields as mapped. This is what's causing this part of the exception. You need to do one of the following:
@XmlAccessorType(XmlAccessType.FIELD)
on your class.I have written more about this on my blog:
Upvotes: 3