Web前端之路

DTD无网络校验

2017-11-30  本文已影响82人  3c69b7c624d9

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
上一篇 下一篇

猜你喜欢

热点阅读