的书 博客园 首页 联系 管理 【死磕 Spring】----- IOC 之 获取 Document 对象

 原文出自:

如果我们再次运行,则会报如下错误:

spring-201806071001

从上面的错误可以看到,是在进行文档验证时,无法根据声明找到 XSD 验证文件而导致无法进行 XML 文件验证。在(

spring-201806071003

我们知道在 Spring 中使用 DelegatingEntityResolver 为 EntityResolver 的实现类,resolveEntity() 实现如下:

    public InputSource resolveEntity(String publicId, @Nullable String systemId) throws SAXException, IOException {         if (systemId != null) {             if (systemId.endsWith(DTD_SUFFIX)) {                 return this.dtdResolver.resolveEntity(publicId, systemId);             }             else if (systemId.endsWith(XSD_SUFFIX)) {                 return this.schemaResolver.resolveEntity(publicId, systemId);             }         }         return null;     }

不同的验证模式使用不同的解析器解析,如果是 DTD 验证模式则使用 BeansDtdResolver 来进行解析,如果是 XSD 则使用 PluggableSchemaResolver 来进行解析。

BeansDtdResolver 的解析过程如下:

    public InputSource resolveEntity(String publicId, @Nullable String systemId) throws IOException {         if (logger.isTraceEnabled()) {             logger.trace("Trying to resolve XML entity with public ID [" + publicId +                     "] and system ID [" + systemId + "]");         }         if (systemId != null && systemId.endsWith(DTD_EXTENSION)) {             int lastPathSeparator = systemId.lastIndexOf('/');             int dtdNameStart = systemId.indexOf(DTD_NAME, lastPathSeparator);             if (dtdNameStart != -1) {                 String dtdFile = DTD_NAME + DTD_EXTENSION;                 if (logger.isTraceEnabled()) {                     logger.trace("Trying to locate [" + dtdFile + "] in Spring jar on classpath");                 }                 try {                     Resource resource = new ClassPathResource(dtdFile, getClass());                     InputSource source = new InputSource(resource.getInputStream());                     source.setPublicId(publicId);                     source.setSystemId(systemId);                     if (logger.isDebugEnabled()) {                         logger.debug("Found beans DTD [" + systemId + "] in classpath: " + dtdFile);                     }                     return source;                 }                 catch (IOException ex) {                     if (logger.isDebugEnabled()) {                         logger.debug("Could not resolve beans DTD [" + systemId + "]: not found in classpath", ex);                     }                 }             }         } or wherever.         return null;     }

从上面的代码中我们可以看到加载 DTD 类型的 BeansDtdResolver.resolveEntity()只是对 systemId 进行了简单的校验(从最后一个 / 开始,内容中是否包含 spring-beans),然后构造一个 InputSource 并设置 publicId、systemId,然后返回。

PluggableSchemaResolver 的解析过程如下:

    public InputSource resolveEntity(String publicId, @Nullable String systemId) throws IOException {         if (logger.isTraceEnabled()) {             logger.trace("Trying to resolve XML entity with public id [" + publicId +                     "] and system id [" + systemId + "]");         }          if (systemId != null) {             String resourceLocation = getSchemaMappings().get(systemId);             if (resourceLocation != null) {                 Resource resource = new ClassPathResource(resourceLocation, this.classLoader);                 try {                     InputSource source = new InputSource(r
                    
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信