Jaxb 对于十进制值,xs:int解组为null

Jaxb 对于十进制值,xs:int解组为null,jaxb,jax-ws,Jaxb,Jax Ws,我遇到了一个与基于JAX-WS的Web服务中的解组过程相关的问题。在WSDL文件中,有一个元素定义为 在相关JAVA类中,它被定义为: @xmlement(name=“Quantity”,required=true,type=Integer.class,nillable=true) 保护整数数量; 如果此元素的XML值是十进制数(3.4)的表示形式,则该元素将被解组为空整数。不会生成SOAPFault,并且不可能在WebService中区分十进制值和空值。 这可能是JAXB实现中的缺陷还是

我遇到了一个与基于JAX-WS的Web服务中的解组过程相关的问题。在WSDL文件中,有一个元素定义为


在相关JAVA类中,它被定义为:

@xmlement(name=“Quantity”,required=true,type=Integer.class,nillable=true)
保护整数数量;
如果此元素的XML值是十进制数(3.4)的表示形式,则该元素将被解组为空整数。不会生成SOAPFault,并且不可能在WebService中区分十进制值和空值。 这可能是JAXB实现中的缺陷还是我做错了什么

这可能是JAXB实现中的缺陷还是我正在做什么 错了吗

这不是实现中的缺陷。这是JAX-WS如何配置为使用JAXB的结果。下面我将用一个例子来演示

根目录

下面是一个域对象,其字段与您的问题中的字段匹配。我已经从
@xmlement
注释中删除了
type=Integer.class
,因为它是冗余的

import javax.xml.bind.annotation.*;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
公共类根{
@xmlement(name=“Quantity”,required=true,nillable=true)
保护整数数量;
}
演示

JAXB提供了在
Unmarshaller
上设置
ValidationEventHandler
的功能,使您能够控制如何处理unmarshal错误

导入java.io.StringReader;
导入javax.xml.bind.*;
公开课演示{
公共静态void main(字符串[]args)引发异常{
JAXBContext jc=JAXBContext.newInstance(Root.class);
Unmarshaller Unmarshaller=jc.createUnmarshaller();
unmarshaller.setEventHandler(新的ValidationEventHandler(){
@凌驾
公共布尔handleEvent(ValidationEvent事件){
System.out.println(event.getMessage());
返回true;
}
});
StringReader xml=新的StringReader(“3.4”);
Root=(Root)unmarshaller.unmarshal(xml);
Marshaller=jc.createMarshaller();
setProperty(marshaller.JAXB_格式化的_输出,true);
marshaller.marshall(root,System.out);
}
}
输出

在专家组中,我们决定无效元素数据是常见的,并且JAXB不应该在每次遇到这种情况时都失败,但是您可以看到出现了一个
ValidationEvent

不是数字:3.4
更新演示

如果我们更新了
ValidationEventHandler
,表明我们不希望在引发
ValidationEvent
时继续
unmarshal
,我们可以进行以下更改

@覆盖
公共布尔handleEvent(ValidationEvent事件){
System.out.println(event.getMessage());
返回false;
}
更新的输出

现在出现以下输出

不是数字:3.4
线程“main”javax.xml.bind.UnmarshaleException中的异常:不是数字:3.4
-除此之外:
[java.lang.NumberFormatException:不是数字:3.4]
位于com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:647)
位于com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleError(UnmarshallingContext.java:676)
位于com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleError(UnmarshallingContext.java:672)
位于com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.handleParseConversionException(Loader.java:256)
位于com.sun.xml.internal.bind.v2.runtime.unmarshaller.leaftPropertyLoader.text(leaftPropertyLoader.java:54)
位于com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.text(UnmarshallingContext.java:499)
位于com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.processText(SAXConnector.java:166)
位于com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.endElement(SAXConnector.java:139)
位于com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endeElement(AbstractSAXParser.java:606)
位于com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scannedelement(XMLDocumentFragmentScannerImpl.java:1742)
位于com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2900)
位于com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:607)
在com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:116)
位于com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:489)
位于com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:835)
位于com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:764)
位于com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:123)
位于com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1210)
位于com.sun.org.apache.xerces.internal.jaxp.saxpasserimpl$jaxpsaxpasser.parse(saxpasserimpl.java:568)
位于com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:203)
位于com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:175)
位于javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157)
位于javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:214)
在论坛上
..
@XmlRootElement(name="MSEPObtenerPolizaFechaDTO")
@XmlAccessorType(XmlAccessType.FIELD)

public class MSEPObtenerPolizaFechaDTO implements Serializable {
..

public void beforeUnmarshal(Unmarshaller unmarshaller, Object parent) throws JAXBException, IOException, SAXException {
        unmarshaller.setSchema(Utils.getSchemaFromContext(this.getClass()));
        unmarshaller.setEventHandler(new CustomEventHandler());
  }

  public void afterUnmarshal(Unmarshaller unmarshaller, Object parent) throws JAXBException {
        unmarshaller.setSchema(null);
        unmarshaller.setEventHandler(null);
  }
public class CustomEventHandler implements ValidationEventHandler{

      @Override
      public boolean handleEvent(ValidationEvent event) {
            if (event.getSeverity() == event.ERROR ||
                        event.getSeverity() == event.FATAL_ERROR)
            {
                  ValidationEventLocator locator = event.getLocator();
                  throw new RuntimeException(event.getMessage(), event.getLinkedException());
            }
            return true;
      }
}
  @SuppressWarnings("unchecked")
  public static Schema getSchemaFromContext(Class clazz) throws JAXBException, IOException, SAXException{
        JAXBContext jc = JAXBContext.newInstance(clazz);
        final List<ByteArrayOutputStream> outs = new ArrayList<ByteArrayOutputStream>();
        jc.generateSchema(new SchemaOutputResolver(){
              @Override
              public Result createOutput(String namespaceUri,
                         String suggestedFileName) throws IOException {
              ByteArrayOutputStream out = new ByteArrayOutputStream();
              outs.add(out);
              StreamResult streamResult = new StreamResult(out);
              streamResult.setSystemId("");
              return streamResult;
              }
        });
        StreamSource[] sources = new StreamSource[outs.size()];
        for (int i = 0; i < outs.size(); i++) {
              ByteArrayOutputStream out = outs.get(i);
              sources[i] = new StreamSource(new ByteArrayInputStream(out.toByteArray()), "");
        }
        SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        return sf.newSchema(sources);
  }