为什么 Jersey 中的 XmlRootElementJaxbProvider 使用 SAXSource
Why does XmlRootElementJaxbProvider in Jersey use SAXSource
阅读 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 的方法。
阅读 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 的方法。