Jaxb2 Jaxb解组器以不同的方式处理Long和Integer

Jaxb2 Jaxb解组器以不同的方式处理Long和Integer,jaxb2,unmarshalling,Jaxb2,Unmarshalling,我有一个带有一个长变量的类,我希望输入xml被解组。当我运行unmarshal(附加单元测试)时,ValidationEventHandler中抛出了以下错误 [severity=ERROR,message=For input string: "",locator=node=null,object=null,url=null,line=1,col=96,offset=-1]] LinkedException: java.lang.NumberFormatException: For input

我有一个带有一个长变量的类,我希望输入xml被解组。当我运行unmarshal(附加单元测试)时,ValidationEventHandler中抛出了以下错误

[severity=ERROR,message=For input string: "",locator=node=null,object=null,url=null,line=1,col=96,offset=-1]]
LinkedException: java.lang.NumberFormatException: For input string: ""
类和单元测试如下所示-

@XmlRootElement
    public class Annotation {

    private Long creatorNo;

    public Long getCreatorNo() {
        return creatorNo;
    }

    public void setCreatorNo(Long creator) {
        creatorNo = creator;
    }
}
单元测试-

public class AnnotationTest {

    @Test
    public void testUnmarshall() throws Exception {
        final String inputXML = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><annotation><creatorNo></creatorNo></annotation>";
        final JAXBContext jaxbContext = JAXBContext.newInstance(Annotation.class);
        final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
        unmarshaller.setEventHandler(new UnmarshallerValidationEventHandler());
        final Annotation annotationObject = (Annotation)unmarshaller.unmarshal(new StringReader(inputXML));
    }
}
公共类注释测试{
@试验
public void testUnmarshall()引发异常{
最终字符串inputXML=“”;
final-JAXBContext-JAXBContext=JAXBContext.newInstance(Annotation.class);
final Unmarshaller Unmarshaller=jaxbContext.createUnmarshaller();
setEventHandler(新的UnmarshallerValidationEventHandler());
最终注释annotationObject=(注释)unmarshaller.unmarshal(新StringReader(inputXML));
}
}
从外观上看,Jaxb不喜欢将空元素传递给Long类型。但是现在,如果我在“Annotation”类中将“creatorNo”的类型改为Integer而不是Long,则不会引发异常,Jaxb只会创建“creatorNo”设置为0的类。那么为什么会有这种不同的行为呢

我所追求的真正行为是,我希望Jaxb将“creatorNo”视为可选的,并将其设置为NULL for和空XML元素。这可能吗


谢谢

注意:我是专家组的负责人和成员

您看到的将空元素转换为
Long
的问题是一个JAXB RI问题,而不是JAXB问题,因为其他实现(如MOXy)正确处理此用例。您可以在以下位置针对JAXB RI记录错误:

解决办法

  • 使用JAXB的另一个实现(JSR-222)没有这个问题,这个选项是编码到标准API的一大好处
  • 如果使用默认的
    ValidationEventHandler
    此转换异常将被忽略,您的文档将按预期解组
  • 使用
    XmlAdapter
    String
    Long
    之间进行转换。您可以利用JAXB的
    DatatypeConverter
    来简化这一过程
  • 更改
    UnmarshallerValidationEventHandler
    的实现,使其更能容忍转换错误
  • 解组验证验证事件处理程序

    import javax.xml.bind.ValidationEvent;
    import javax.xml.bind.ValidationEventHandler;
    
    public class UnmarshallerValidationEventHandler implements ValidationEventHandler {
    
        @Override
        public boolean handleEvent(ValidationEvent event) {
            return event.getSeverity() < ValidationEvent.FATAL_ERROR;
        }
    
    }
    
    import javax.xml.bind.ValidationEvent;
    导入javax.xml.bind.ValidationEventHandler;
    公共类解组器ValidationEventHandler实现ValidationEventHandler{
    @凌驾
    公共布尔handleEvent(ValidationEvent事件){
    返回事件。getSeverity()
    注意:我是专家组的负责人和成员

    您看到的将空元素转换为
    Long
    的问题是一个JAXB RI问题,而不是JAXB问题,因为其他实现(如MOXy)正确处理此用例。您可以在以下位置针对JAXB RI记录错误:

    解决办法

  • 使用JAXB的另一个实现(JSR-222)没有这个问题,这个选项是编码到标准API的一大好处
  • 如果使用默认的
    ValidationEventHandler
    此转换异常将被忽略,您的文档将按预期解组
  • 使用
    XmlAdapter
    String
    Long
    之间进行转换。您可以利用JAXB的
    DatatypeConverter
    来简化这一过程
  • 更改
    UnmarshallerValidationEventHandler
    的实现,使其更能容忍转换错误
  • 解组验证验证事件处理程序

    import javax.xml.bind.ValidationEvent;
    import javax.xml.bind.ValidationEventHandler;
    
    public class UnmarshallerValidationEventHandler implements ValidationEventHandler {
    
        @Override
        public boolean handleEvent(ValidationEvent event) {
            return event.getSeverity() < ValidationEvent.FATAL_ERROR;
        }
    
    }
    
    import javax.xml.bind.ValidationEvent;
    导入javax.xml.bind.ValidationEventHandler;
    公共类解组器ValidationEventHandler实现ValidationEventHandler{
    @凌驾
    公共布尔handleEvent(ValidationEvent事件){
    返回事件。getSeverity()