为什么Jersey中的XmlRootElementJaxbProvider使用SAXSource

时间:2016-04-04 14:11:28

标签: java jaxb jersey jersey-2.0

通过泽西岛来源,我注意到one of the default MessageBodyReader implementations创建了一个SAXSource,然后传递给Unmarshaller

@Override
protected Object readFrom(Class<Object> type, MediaType mediaType,
        Unmarshaller u, InputStream entityStream)
        throws JAXBException {
    final SAXSource s = getSAXSource(spf.provide(), entityStream);
    if (type.isAnnotationPresent(XmlRootElement.class)) {
        return u.unmarshal(s);
    } else {
        return u.unmarshal(s, type).getValue();
    }
}

我的问题:为什么InputStream包裹在SAXSource

Unmarshaller.unmarshal可以自行接受InputStreamcom.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl似乎使用相同的内部方法进行解组,无论是SAXSource还是InputStream 。唯一的区别似乎是XmlRootElementJaxbProvider使用依赖注入来提供用于获取Factory<SAXParserFactory>的{​​{1}},而在SAXParserFactory的方法中使用UnmarshallerImpl方法SAXParserFactory.newInstance()直接调用。希望能够注入自定义SAXParserFactoryunmarshaller.unmarshal(SAXSource)代替unmarshaller.unmarshal(InputStream)的唯一原因吗?

1 个答案:

答案 0 :(得分:0)

Git责备是你的朋友。最初的实现(早在2009年)使用了StreamSource。更改的原因是错误,https://java.net/jira/browse/JERSEY-323

当时,是的,SAXParserFactory.newInstance()被直接调用,但代码然后在解析器上设置各种功能(可能这些功能当时没有由JAXB设置)。你可以在这里看到:https://github.com/jersey/jersey-1.x/blob/2057807f211958860a7557abf49ac4cd6a5ef1fb/jersey-core/src/main/java/com/sun/jersey/core/impl/provider/xml/SAXParserContextProvider.java

我不确定这种改变是否仍然是必要的,但这是改变的最初动机。从那时起,代码似乎已经相对未经修改地通过了。

变化的完全差异是here,尽管它并不是非常明显。 readFrom方法已添加到XmlRootElementProvider中,以覆盖在AbstractRootElementProvider中使用StreamSource的方法。