我有jaxb类,如下所示,我希望我的xmlAdapter格式的日期值,我得到例外?
引起:java.lang.RuntimeException:com.sun.xml.bind.v2.runtime.IllegalAnnotationsException:IllegalAnnotationExceptions的1个计数 无效的@XmlElementRef:类型“class java.lang.String”或其任何子类都不为此上下文所知。
以下代码有什么问题?
@XmlElementRef(name="endDate")
@XmlJavaTypeAdapter(DateAdapter.class)
protected JAXBElement<Date> endDate;
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;
}
}
答案 0 :(得分:0)
有两种可能的决定:
只需将@XmlElementRef替换为@XmlElement,并在编组方法中将dateFormat.format(v)
替换为dateFormat.format(v).getValue()
。
如果您正在使用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);
}