EntityResolver是org.xml.sax包下的一个接口(InputSource也是)
1.1 何为 EntityResolver :
官方解释: 如果SAX应用程序实现自定义处理外部实体,则必须实现此接口,
并使用setEntityResolver方法向SAX 驱动器注册一个实例.
也就是说,对于解析一个xml,sax
首先会读取该xml文档上的声明,根据声明去寻找相应的dtd定义,以便对文档的进行验证,
默认的寻找规则,(即:通过网络,实现上就是声明DTD的地址URI地址来下载DTD声明),
并进行认证,下载的过程是一个漫长的过程,而且当网络不可用时,这里会报错,就是因为相应的dtd没找到,
1.2 EntityResolver 的作用就是项目本身就可以提供一个如何寻找DTD 的声明方法,
即:由程序来实现寻找DTD声明的过程,比如我们将DTD放在项目的某处在实现时直接将此文档读取并返回个SAX即可,这样就避免了通过网络来寻找DTD的声明
1.3 首先看看EntityResolver 接口声明的方法.
这里,他接收2个参数,publicId ,systemId ,并返回一个InputStream对象,
这里我们以特定的文件来讲解;
1.3.1 如果我们在解析验证模式为xsd的配置文件,代码如下
读取得到以下参数,
publicId : null
systemId : http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
1.3.2 如果我们解析的是DTD的配置文件;
读取得到以下参数:
publicId : -//SPRING//DTD BEAN//EN
systemId : http://www.springframework.org/dtd/spring-beans.dtd
之前已经提到过,默认的寻找规则,(即:通过网络,实现上就是声明DTD的地址URI地址来下载DTD声明),这样才会造成延迟,用户体验也不好,一般的做法是将验证文件放在自己的工程里面,那么怎么做才能将这个Url转换为自己工程里对应的文件呢?我们已加载DTD文件为例看看Spring中是如通过getEntityResolver() 对 EntityResolver 的获取,
1.4 DelegatingEntityResolver
Spring中使用DelegatingEntityResolver 类为 EntityResolver的实现类,
EntityResolver 的实现方法如下
我们可以看到,对不同的验证模式,dtd使用了BeansDtdResolver,xsd使用了PluggableSchemaResolver。 这些XXXResolver都是实现了Resolver的resolveEntity接口。
BeansDtdResolver
PluggableSchemaResolver