在阅读Jersey的源代码时,我注意到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可以自己接受InputStream,并且com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl似乎使用相同的内部方法来解组是否提供了SAXSourceInputStream。唯一的区别似乎是XmlRootElementJaxbProvider使用依赖项注入来提供Factory<SAXParserFactory>来获取SAXParserFactory,而在UnmarshallerImpl的肠道中直接调用方法SAXParserFactory.newInstance()。是否希望能够注入自定义SAXParserFactory而不是使用unmarshaller.unmarshal(SAXSource)而不是unmarshaller.unmarshal(InputStream)的唯一原因?

最佳答案

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的方法。

10-04 20:06