我有一个构建响应对象的大型Web服务,依赖于JAXB将其编组为要返回的最终XML。在那个对象中,我有许多Date字段。某些日期字段不得包含时区信息,而某些日期字段则必须(基于奇怪的业务规则)。
在多年来没有变化的代码中,对于那些必须没有TZ信息的日期,我们有一个自定义类型适配器来完成我们需要的工作。对于所有其他领域,我们让JAXB为我们处理它:编组和解组日期以包含TZ信息。
对于服务的新版本的每个版本,我们都有一个自定义回归系统,以确保响应的一个字节不会从已知的良好响应中发生变化。在我们最近的版本中,我们有一个问题会定期出现在TZ预期的那些日期,它已经缺失:
Old Value:2014-05-14T08:24:20.283-04:00
New Value:2014-05-14T08:24:20.283Z
令人沮丧的是,当我们再次针对失败的请求运行测试时,第二次测试通过:意味着TZ返回。当bug无法按需复制时很难调试。
我可以找到的代码中没有任何地方,并且在所有依赖项中,系统都在不断更改JVM TimeZone,或者我可以找到的默认格式(Locale.setDefault)。
有没有人看到这种类型的JAXB与日期不一致?
我们可以编写另一个自定义适配器来强制进行编组以获得TZ ...但我不明白为什么现在,经过多年的使用,突然决定改变我们。
UPDATE 这是新的适配器。没有什么特别的。但是,就像我说的,这个问题发生在添加此适配器之前。在它添加之后,我不知道它是否已经解决了......没时间进行测试了。
public class CustomDateTimeTZAdapter extends XmlAdapter<String, Date>{
private static DateFormat getFormatter() {
return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); // <---------------- NOTE: The "XXX" for Timezone is only JAVA 7+ supported!
}
@Override
public Date unmarshal(String v) throws Exception {
try {
return getFormatter().parse(v);
} catch (ParseException e) {
return null;
}
}
@Override
public String marshal(Date v) throws Exception {
if (v != null) {
return getFormatter().format(v);
} else {
return null;
}
}
}