为JAXB转换创建Timestamp适配器

时间:2014-06-30 11:36:40

标签: java xml jaxb

我目前正在尝试使用JAXB库进行XML到POJO的转换。我有一个课程如下:

class Student {

 String name;
 Integer id;
 Date dateOfBirth;
 @XmlJavaTypeAdapter(TimeDateAdapter.class)
 Timestamp admitTime;

 //constructor and getter setters

}

现在我想通过XML输入这些字段。所以我重现了xml:

  <student>
    <name>Student 1</name>
    <id>123</id>
    <dob>29-02-1991</dob>
    <admitTime>231441321413</admitTime>
  </student>

因此,您可能知道它会抛出一个错误,说它无法转换Timestamp,因为Timestamp类中没有no-arg构造函数。所以我将不得不创建一个适配器。所以,我想知道是否有一种方法可以为Date,timestamp和Calendar创建一个通用适配器,以便根据实现方式对它们进行解组和编组?

编辑:我创建了一个适配器,用于编组和解组我的java.sql.Timestamp对象和从xml解组。这是代码:

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));
    }

}

它给了我以下错误:

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)

1 个答案:

答案 0 :(得分:3)

JAXB(JSR-222)实现默认支持java.util.Datejava.util.Calendar,因此您不需要XmlAdapterjava.sql.Datejava.sql.Timejava.sql.Timestamp等类需要XmlAdapter。我建议使用单独的适配器,而不是尝试将它们组合成一个。

注意

可以在包级别指定XmlAdapter。当这样做时,它适用于属于该包中的域类的该类型的所有映射字段/属性。这可以大大减少您需要指定@XmlJavaTypeAdapter的次数。您可以在我的博客上阅读有关此方法的更多信息。


更新

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

默认情况下,JAXB将公共属性(获取/设置方法对)和带注释的字段视为映射。这就是造成这部分异常的原因。您需要执行以下操作之一:

  1. 注释get方法而不是字段。
  2. 在字段上保留注释,并在您的课程中指定@XmlAccessorType(XmlAccessType.FIELD)
  3. 我在博客上写了更多关于此的内容: