在阅读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
似乎使用相同的内部方法来解组是否提供了SAXSource
或InputStream
。唯一的区别似乎是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的方法。