栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring中的Document

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring中的Document

上一篇文章已经介绍了Spring中XML的验证方式.接着讲Spring是如何把配置文件解析成Document的.

Document

	@Override
	public Document loadDocument(InputSource inputSource, EntityResolver entityResolver,
			ErrorHandler errorHandler, int validationMode, boolean namespaceAware) throws Exception {
		// 1、创建DocumentBuidlerFactory
		DocumentBuilderFactory factory = createDocumentBuilderFactory(validationMode, namespaceAware);
		if (logger.isTraceEnabled()) {
			logger.trace("Using JAXP provider [" + factory.getClass().getName() + "]");
		}
		// 2、通过DocumentBuidlerFactory创建DocumentBuilder
		DocumentBuilder builder = createDocumentBuilder(factory, entityResolver, errorHandler);
		// 3、通过DocumentBuilder创建Document
		return builder.parse(inputSource);
	}

因为通过SAX解析XML文档的套路大致都差不多,所以这里不再多说.
但是该方法有一个参数需要注意:entityResolver
这里再贴一遍进入这个方法之前的代码:

protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {
		return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,
				getValidationModeForResource(resource), isNamespaceAware());
	}

可以看到entityResolver是通过getEntityResolver来获取的.
那什么是entityResolver?

EntityResolver
官网:如果SAX应用程序需要实现自定义处理外部实体,则必须实现此接口并且使用setEntityResolver方法向SAX驱动器注册一个实体.
也就是说,对于解析一个XML文件,SAX首先读取该XML文档上的声明,根据声明去寻找相应的DTD定义,以便对文档进行一个验证.
而默认的寻找规则是通过网络(就是通过声明的DTD的URI地址)下载相应的DTD声明,并进行认证.但是因为下载的过程中可能因为网络中断或不可用,导致这里报错,因为她会认为你的DTD声明没有被找到.
EntityResolver的作用是项目本身就可以提供一个如何寻找DTD声明的方法,即由程序来实现寻找DTD声明的过程,比如我们把这个DTD文件放到项目中某处,在实现时直接将此文档读取并返回给SAX即可.

下面逐一介绍EntityResolver的获取和使用.
1、getEntityResolver()的代码如下:

	protected EntityResolver getEntityResolver() {
		if (this.entityResolver == null) {
			// Determine default EntityResolver to use.
			ResourceLoader resourceLoader = getResourceLoader();
			if (resourceLoader != null) {
				this.entityResolver = new ResourceEntityResolver(resourceLoader);
			}
			else {
				this.entityResolver = new DelegatingEntityResolver(getBeanClassLoader());
			}
		}
		return this.entityResolver;
	}

2、将URL转化为自己工程中对应的文件地址
先介绍下entityResolver的工作原理
接口方法声明

    public abstract InputSource resolveEntity (String publicId,
                                               String systemId)
        throws SAXException, IOException;

注意这里有两个参数:publicId、systemId
分别使用两种方式的验证模式进行说明,这两个参数接受值.

  1. XSD模式的配置文件



那么两个参数的值为:

  • publicId:null
  • systemId:https://maven.apache.org/xsd/maven-4.0.0.xsd
  1. DTD模式的配置文件




那么两个参数的值为:

  • publicId: -//mybatis.org//DTD Mapper 3.0//EN
  • systemId: http://mybatis.org/dtd/mybatis-3-mapper.dtd

那么Spring是如何把URL转化为自己工程里文件的呢?
根据前面获取entityResolver的代码,可以知道,EntityResolver的实现类中有一个DelegatingEntityResolver.那么看一下这个实现类中的resolveEntity.

public InputSource resolveEntity(@Nullable String publicId, @Nullable String systemId)
			throws SAXException, IOException {
			// 通过上面的原理分析,不管是XSD还是DTD,systemId都不为空
		if (systemId != null) {
			// 判断systemId是否是以dtd后缀结尾
			if (systemId.endsWith(DTD_SUFFIX)) {
				// 如果是则使用 dtdResolver解析dtd,
				// 直接截取systemId最后的xx.dtd,然后去当前路径下寻找
				return this.dtdResolver.resolveEntity(publicId, systemId);
			}
			// 是否是以xsd结尾
			else if (systemId.endsWith(XSD_SUFFIX)) {
				// 如果是则使用schemaResolver解析
				//通过调用META-INF/spring.schemas文件中找到systemid所对应的XSD文件
				return this.schemaResolver.resolveEntity(publicId, systemId);
			}
		}
		// Fall back to the parser's default behavior.
		return null;
	}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/877840.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号