格式化jaxb元素日期

时间:2014-07-17 10:26:52

标签: java jaxb marshalling

我有jaxb类,如下所示,我希望我的xmlAdapter格式的日期值,我得到例外?

引起:java.lang.RuntimeException:com.sun.xml.bind.v2.runtime.IllegalAnnotationsException:IllegalAnnotationExceptions的1个计数 无效的@XmlElementRef:类型“class java.lang.String”或其任何子类都不为此上下文所知。

以下代码有什么问题?

Jaxb类

@XmlElementRef(name="endDate")
@XmlJavaTypeAdapter(DateAdapter.class)
protected JAXBElement<Date> endDate;

DateAdaptor类,用于格式化jaxbelement日期值

    public class DateAdapter extends XmlAdapter<String, JAXBElement<Date>>
    {
    private final String TIMEZONE_US_EASTERN = "US/Eastern";

    private final String LOCALE_LANGUAGE_EN = "en";

    private final String LOCALE_COUNTRY_US = "US";

    private final String DATE_FORMAT = "yyyy-MM-dd";

    private SimpleDateFormat dateFormat = null;

    private TimeZone timeZone = null;

    private Locale locale = null;

    public DateAdapter() {
        locale = new Locale(LOCALE_LANGUAGE_EN, LOCALE_COUNTRY_US);
        dateFormat = new SimpleDateFormat(DATE_FORMAT,locale);
        timeZone = TimeZone.getTimeZone(TIMEZONE_US_EASTERN);
    }

    @Override
    public String marshal(JAXBElement<Date> v) throws Exception {
        String timezone = getBasisForGivenDate(v.getValue());
        String startDayTime = "T23:59:59"+timezone;
        dateFormat.setTimeZone(timeZone);
        return dateFormat.format(v)+startDayTime;
    }


    @Override
    public JAXBElement<Date> unmarshal(String v) throws Exception {
        return null;
    }


    public String getBasisForGivenDate(Date date) {

        String basis = "-05:00";
        TimeZone jvmTimeZone = TimeZone.getDefault();

        if (jvmTimeZone.inDaylightTime(date)) {
            basis = "-04:00";
        }
        return basis;
    }
 }

1 个答案:

答案 0 :(得分:0)

有两种可能的决定:

  1. 只需将@XmlElementRef替换为@XmlElement,并在编组方法中将dateFormat.format(v)替换为dateFormat.format(v).getValue()

  2. 如果您正在使用ObjectFactory进行对象创建,例如

    @XmlRegistry
    public class ObjectFactory {
    
    @XmlElementDecl(name = "endDate", scope=EntityTest.class)
    JAXBElement<Date> createEndDate(Date value) {
        return new JAXBElement<Date>(new QName("endDate"), Date.class, value);
    }
    

    }

  3. 和实体类是

        @XmlRootElement
        public class EntityTest {
    
        @XmlElementRef(type=JAXBElement.class, name="endDate")
        @XmlJavaTypeAdapter(DateAdapter.class)
        protected JAXBElement<Date> endDate;
    
    
        public void setEndDate(JAXBElement<Date> endDate) {
            this.endDate = endDate;
        }
    }
    

    然后你的DateAdapter应该是这样的:

    public class DateAdapter extends XmlAdapter<JAXBElement<String>, JAXBElement<Date>> {
        private final String TIMEZONE_US_EASTERN = "US/Eastern";
        private final String LOCALE_LANGUAGE_EN = "en";
        private final String LOCALE_COUNTRY_US = "US";
        private final String DATE_FORMAT = "yyyy-MM-dd";
        private SimpleDateFormat dateFormat = null;
        private TimeZone timeZone = null;
        private Locale locale = null;
    
        public DateAdapter() {
            locale = new Locale(LOCALE_LANGUAGE_EN, LOCALE_COUNTRY_US);
            dateFormat = new SimpleDateFormat(DATE_FORMAT, locale);
            timeZone = TimeZone.getTimeZone(TIMEZONE_US_EASTERN);
        }
    
        @Override
        public JAXBElement<String> marshal(JAXBElement<Date> v) throws Exception {
            String timezone = getBasisForGivenDate(v.getValue());
            String startDayTime = "T23:59:59" + timezone;
            dateFormat.setTimeZone(timeZone);
            return new JAXBElement<String>(v.getName(), String.class, dateFormat.format(v.getValue()) + startDayTime);
        }
    
        @Override
        public JAXBElement<Date> unmarshal(JAXBElement<String> v) throws Exception {
            return null;
        }
    
        public String getBasisForGivenDate(Date date) {
            String basis = "-05:00";
            TimeZone jvmTimeZone = TimeZone.getDefault();
    
            if (jvmTimeZone.inDaylightTime(date)) {
                basis = "-04:00";
            }
            return basis;
        }
    }
    

    注意:SimpleDateFormat不是线程安全的,在单例中使用它会导致多线程环境中的错误。

    检查工作的单元测试:

    @Test
    public void testMarshaler() throws Exception {
        EntityTest entity = new EntityTest();
        JAXBElement<Date> date = new ObjectFactory().createEndDate(new Date());
        entity.setEndDate(date);
        JAXBContext context = JAXBContext.newInstance(EntityTest.class, ObjectFactory.class);
        Marshaller marshaller = context.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false);
        marshaller.marshal(entity, System.out);
    
    }
    
相关问题