【问题标题】:Format jaxb element Date格式化 jaxb 元素日期
【发布时间】:2014-07-17 10:26:52
【问题描述】:

我有像下面这样的 jaxb 类,我希望我的 xmlAdapter 格式化日期值,但我得到了异常?

原因:java.lang.RuntimeException: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 个 IllegalAnnotationExceptions 计数 无效的 @XmlElementRef : 类型“class java.lang.String”或其任何子类在此上下文中是未知的。

下面的代码有什么问题?

Jaxb 类

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

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

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

【问题讨论】:

  • 你得到了什么异常?
  • 用异常更新问题
  • 请添加编组代码,如何创建 JAXBContext?
  • 返回Response.status(Status.OK).entity(JaxbObject).build();
  • 您确定 XmlElementRef 注释吗?尝试将其更改为 XmlElement

标签: java jaxb marshalling


【解决方案1】:

有两种可能的决定:

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

    }

实体类是

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

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-28
    • 2016-04-23
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-09
    • 1970-01-01
    相关资源
    最近更新 更多