DTD无网络校验

作者: 3c69b7c624d9 | 来源:发表于2017-11-30 02:04 被阅读82次

    Java的发展绝对离不开XML的贡献。

    对于xml的定义文件通常使用dtd和xsd。xsd,dtd,tld有什么区别和联系?

    我们重点描述一下关于校验的问题。

    参考笔者多年前的问题spring 3.0如何增加无网络环境dtd文件免校验

    我们看一下最常用的mybatis的xml是如何实现的

        /**
         * Offline entity resolver for the MyBatis DTDs
         *
         * @author Clinton Begin
         */
        public class XMLMapperEntityResolver implements EntityResolver {
         
          private static final Map<String, String> doctypeMap = new HashMap<String, String>();
         
          private static final String IBATIS_CONFIG_PUBLIC = "-//ibatis.apache.org//DTD Config 3.0//EN".toUpperCase(Locale.ENGLISH);
          private static final String IBATIS_CONFIG_SYSTEM = "http://ibatis.apache.org/dtd/ibatis-3-config.dtd".toUpperCase(Locale.ENGLISH);
         
          private static final String IBATIS_MAPPER_PUBLIC = "-//ibatis.apache.org//DTD Mapper 3.0//EN".toUpperCase(Locale.ENGLISH);
          private static final String IBATIS_MAPPER_SYSTEM = "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd".toUpperCase(Locale.ENGLISH);
         
          private static final String MYBATIS_CONFIG_PUBLIC = "-//mybatis.org//DTD Config 3.0//EN".toUpperCase(Locale.ENGLISH);
          private static final String MYBATIS_CONFIG_SYSTEM = "http://mybatis.org/dtd/mybatis-3-config.dtd".toUpperCase(Locale.ENGLISH);
         
          private static final String MYBATIS_MAPPER_PUBLIC = "-//mybatis.org//DTD Mapper 3.0//EN".toUpperCase(Locale.ENGLISH);
          private static final String MYBATIS_MAPPER_SYSTEM = "http://mybatis.org/dtd/mybatis-3-mapper.dtd".toUpperCase(Locale.ENGLISH);
         
          private static final String MYBATIS_CONFIG_DTD = "org/apache/ibatis/builder/xml/mybatis-3-config.dtd";
          private static final String MYBATIS_MAPPER_DTD = "org/apache/ibatis/builder/xml/mybatis-3-mapper.dtd";
         
          static {
            doctypeMap.put(IBATIS_CONFIG_SYSTEM, MYBATIS_CONFIG_DTD);
            doctypeMap.put(IBATIS_CONFIG_PUBLIC, MYBATIS_CONFIG_DTD);
         
            doctypeMap.put(IBATIS_MAPPER_SYSTEM, MYBATIS_MAPPER_DTD);
            doctypeMap.put(IBATIS_MAPPER_PUBLIC, MYBATIS_MAPPER_DTD);
         
            doctypeMap.put(MYBATIS_CONFIG_SYSTEM, MYBATIS_CONFIG_DTD);
            doctypeMap.put(MYBATIS_CONFIG_PUBLIC, MYBATIS_CONFIG_DTD);
         
            doctypeMap.put(MYBATIS_MAPPER_SYSTEM, MYBATIS_MAPPER_DTD);
            doctypeMap.put(MYBATIS_MAPPER_PUBLIC, MYBATIS_MAPPER_DTD);
          }
         
          /*
           * Converts a public DTD into a local one
           *
           * @param publicId The public id that is what comes after "PUBLIC"
           * @param systemId The system id that is what comes after the public id.
           * @return The InputSource for the DTD
           *
           * @throws org.xml.sax.SAXException If anything goes wrong
           */
          @Override
          public InputSource resolveEntity(String publicId, String systemId) throws SAXException {
         
            if (publicId != null) {
              publicId = publicId.toUpperCase(Locale.ENGLISH);
            }
            if (systemId != null) {
              systemId = systemId.toUpperCase(Locale.ENGLISH);
            }
         
            InputSource source = null;
            try {
              String path = doctypeMap.get(publicId);
              source = getInputSource(path, source);
              if (source == null) {
                path = doctypeMap.get(systemId);
                source = getInputSource(path, source);
              }
            } catch (Exception e) {
              throw new SAXException(e.toString());
            }
            return source;
          }
         
          private InputSource getInputSource(String path, InputSource source) {
            if (path != null) {
              InputStream in;
              try {
                in = Resources.getResourceAsStream(path);
                source = new InputSource(in);
              } catch (IOException e) {
                // ignore, null is ok
              }
            }
            return source;
          }
         
        }
    

    当我们使用mybatis的时候通常会在xml中映射到

        <?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    

    当xml解析的时候会在

        org/apache/ibatis/builder/xml/mybatis-3-config.dtd
    
    125927_xA0n_871390.png125927_xA0n_871390.png

    由此可见就会正常的加载到。那么如果使用jar版本比较低而声明的xsd或dtd在jar中不能正确映射的话那么要去网络上获取该文件。

    那么在网络不行的情况下(无网络)就会出现应用无法启动的问题了。解决方法自然要去查看一下报错的校验对应的声明和jar是否匹配。

    如下是spring3.2的描述文件,因此如果使用了spring4的声明就会报错(无网络),通常jar提供者会兼容之前的dtd或xsd文件

        http\://www.springframework.org/schema/aop/spring-aop-2.0.xsd=org/springframework/aop/config/spring-aop-2.0.xsd
        http\://www.springframework.org/schema/aop/spring-aop-2.5.xsd=org/springframework/aop/config/spring-aop-2.5.xsd
        http\://www.springframework.org/schema/aop/spring-aop-3.0.xsd=org/springframework/aop/config/spring-aop-3.0.xsd
        http\://www.springframework.org/schema/aop/spring-aop-3.1.xsd=org/springframework/aop/config/spring-aop-3.1.xsd
        http\://www.springframework.org/schema/aop/spring-aop-3.2.xsd=org/springframework/aop/config/spring-aop-3.2.xsd
        http\://www.springframework.org/schema/aop/spring-aop.xsd=org/springframework/aop/config/spring-aop-3.2.xsd
    

    相关文章

      网友评论

        本文标题:DTD无网络校验

        本文链接:https://www.haomeiwen.com/subject/loymbxtx.html