【问题标题】:xsd:datetime and XmlGregorianCalendar causes NullPointerExceptionxsd:datetime 和 XmlGregorianCalendar 导致 NullPointerException
【发布时间】:2010-03-23 17:50:44
【问题描述】:

以下作品:

public Date getDate() {
    return date;
}

并产生类似的东西:

<date>2010-03-23T17:43:50.879Z</date>

我可以使用 XmlGregorianCalendar 返回 xsd:date 或 xsd:time 类型:

@XmlSchemaType(name="date")
public XmlGregorianCalendar getDate() {
    return date;
}

产生类似的东西:

<date>2010-03-23</date>

但尝试像这样返回 xsd:datetime:

@XmlSchemaType(name="datetime")
public XmlGregorianCalendar getDate() {
     return date;
}

导致此堆栈跟踪:

java.lang.NullPointerException
    at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl.checkXmlGregorianCalendarFieldRef(RuntimeBuiltinLeafInfoImpl.java:864)
    at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl.access$200(RuntimeBuiltinLeafInfoImpl.java:111)
    at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl$13.print(RuntimeBuiltinLeafInfoImpl.java:536)
...snip...
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:619)

根本没有提到我的代码。

我使用的是 tomcat 6.0.24,java 1.6.0_16-b01

【问题讨论】:

    标签: java datetime tomcat jaxb jax-ws


    【解决方案1】:

    嗯,我发现了基本问题:应该是"dateTime" 而不是"datetime",但是这有很多更深层次的方面。

    首先,跟踪给我的帮助很少,我花了一段时间才找到正确的来源 (jaxb-ri-2_2.src.zip)。第 864 行是这样的:

    int bitField = xmlGregorianCalendarFieldRef.get(type);
    

    xmlGregorianCalendarFieldRef定义为:

    private static final Map<QName, Integer> xmlGregorianCalendarFieldRef =
                new HashMap<QName, Integer>();
        static {
                Map<QName, Integer> f = xmlGregorianCalendarFieldRef;
                f.put(DatatypeConstants.DATETIME,   0x1111111);
                f.put(DatatypeConstants.DATE,       0x1111000);
                f.put(DatatypeConstants.TIME,       0x1000111);
                f.put(DatatypeConstants.GDAY,       0x1001000);
                f.put(DatatypeConstants.GMONTH,     0x1010000);
                f.put(DatatypeConstants.GYEAR,      0x1100000);
                f.put(DatatypeConstants.GYEARMONTH, 0x1110000);
                f.put(DatatypeConstants.GMONTHDAY,  0x1011000);
        }
    

    所以xmlGregorianCalendarFieldRef 本身不能为 null,但如果使用映射中不存在的键调用 get(),它将返回 null,并且当 JVM 尝试时将抛出 NullPointerException拆箱。

    这段代码有点草率;没有检查类型值,这就是为什么我们会收到这条相当神秘的消息。

    显然我随后查找了DatatypeConstants.DATETIME 的值并发现了大小写错误。

    这也让我相信我应该使用类似的东西:

    @XmlSchemaType(name=DatatypeConstants.DATETIME)
    public XmlGregorianCalendar getDate() {
        return date;
    }
    

    为了增加保护,但是该常量是QName 而不是字符串。

    【讨论】:

      猜你喜欢
      • 2016-03-07
      • 2017-05-16
      • 1970-01-01
      • 2014-06-09
      • 2015-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多