mybatis,Spring等⼯具对xml⽂件正确性的验证
  我们知道mybatis或者spring都是使⽤xml⽂件作为配置⽂件,配置⽂件的格式都是定义在叫做.dtd或者.xsd⽂件中的,当⼯具在解析⽤户⾃⼰定义的xml⽂件的时候,如何才能知道⽤户⾃定义的⽂件是否正确的呢?我们不能在xml⽂件中乱写⼀些框架不认识的标签,⽐如在spring的xml⽂件中写如下<user>标签,毫⽆疑问会报错。那么框架是怎么来验证我们所写的标签是否正确的呢?
<user>
<id>100</id>
</user>
  由于mybatis使⽤的是dom解析,利⽤JDK的dom解析API,如下:
1    @Test
2public void docFactoryTest() throws Exception {
3        DocumentBuilderFactory factory = wInstance();
4        factory.setValidating(true);
5        factory.setNamespaceAware(false);
6        factory.setIgnoringComments(true);
7        factory.setIgnoringElementContentWhitespace(false);
8        factory.setCoalescing(false);
9        factory.setExpandEntityReferences(true);
10        DocumentBuilder builder = wDocumentBuilder();
11        builder.setEntityResolver(new XMLMapperEntityResolver());
      ...(此处省略⼀部分代码)
30        Document doc = builder.ResourceAsStream("l"));
31        println(doc);
  在第11⾏中,⽤到了XMLMapperEntityResolver对象,这个对象定义如下:
1public class XMLMapperEntityResolver implements EntityResolver {
2
3private static final Map<String, String> doctypeMap = new HashMap<String, String>();
4
5private static final String IBATIS_CONFIG_PUBLIC = "-////DTD Config 3.0//EN".toUpperCase(Locale.ENGLISH);
6private static final String IBATIS_CONFIG_SYSTEM = "/dtd/ibatis-3-config.dtd".toUpperCase(Locale.ENGLISH);
7
8private static final String IBATIS_MAPPER_PUBLIC = "-////DTD Mapper 3.0//EN".toUpperCase(Locale.ENGLISH);
9private static final String IBATIS_MAPPER_SYSTEM = "/dtd/ibatis-3-mapper.dtd".toUpperCase(Locale.ENGLISH);
10
11private static final String MYBATIS_CONFIG_PUBLIC = "-////DTD Config 3.0//EN".toUpperCase(Locale.ENGLISH);
12private static final String MYBATIS_CONFIG_SYSTEM = "/dtd/mybatis-3-config.dtd".toUpperCase(Locale.ENGLISH);spring怎么读取xml文件
13
14private static final String MYBATIS_MAPPER_PUBLIC = "-////DTD Mapper 3.0//EN".toUpperCase(Locale.ENGLISH);
15private static final String MYBATIS_MAPPER_SYSTEM = "/dtd/mybatis-3-mapper.dtd".toUpperCase(Locale.ENGLISH);
16
17private static final String MYBATIS_CONFIG_DTD = "org/apache/ibatis/builder/xml/mybatis-3-config.dtd";
18private static final String MYBATIS_MAPPER_DTD = "org/apache/ibatis/builder/xml/mybatis-3-mapper.dtd";
19
20static {
21    doctypeMap.put(IBATIS_CONFIG_SYSTEM, MYBATIS_CONFIG_DTD);
22    doctypeMap.put(IBATIS_CONFIG_PUBLIC, MYBATIS_CONFIG_DTD);
23
24    doctypeMap.put(IBATIS_MAPPER_SYSTEM, MYBATIS_MAPPER_DTD);
25    doctypeMap.put(IBATIS_MAPPER_PUBLIC, MYBATIS_MAPPER_DTD);
26
27    doctypeMap.put(MYBATIS_CONFIG_SYSTEM, MYBATIS_CONFIG_DTD);
28    doctypeMap.put(MYBATIS_CONFIG_PUBLIC, MYBATIS_CONFIG_DTD);
29
30    doctypeMap.put(MYBATIS_MAPPER_SYSTEM, MYBATIS_MAPPER_DTD);
31    doctypeMap.put(MYBATIS_MAPPER_PUBLIC, MYBATIS_MAPPER_DTD);
32  }
33
34/*
35  * Converts a public DTD into a local one
36  *
37  * @param publicId The public id that is what comes after "PUBLIC"
38  * @param systemId The system id that is what comes after the public id.
39  * @return The InputSource for the DTD
40  *
41  * @l.sax.SAXException If anything goes wrong
42*/
43  @Override
44public InputSource resolveEntity(String publicId, String systemId) throws SAXException {
45
46if (publicId != null) {
47      publicId = UpperCase(Locale.ENGLISH);
48    }
49if (systemId != null) {
50      systemId = UpperCase(Locale.ENGLISH);
51    }
52
53    InputSource source = null;
54try {
55      String path = (publicId);
56      source = getInputSource(path, source);
57if (source == null) {
58        path = (systemId);
59        source = getInputSource(path, source);
60      }
61    } catch (Exception e) {
62throw new String());
63    }
64return source;
65  }
66
67private InputSource getInputSource(String path, InputSource source) {
68if (path != null) {
69      InputStream in;
70try {
71        in = ResourceAsStream(path);
72        source = new InputSource(in);
73      } catch (IOException e) {
74// ignore, null is ok
75      }
76    }
77return source;
78  }
79
80 }
  可以看到,当框架在解析xml⽂件的时候,会把xml⽂件开头的publicId和systemId传给EntityResolver,
⽽EntityResolver对象就是从classpath中去寻.dtd⽂件(⽂件就在org/apache/ibatis/builder/xml/⽬录下),在spring中还会存在.xsd⽂件,原理都是⼀样的,然后利⽤classpath中的.dtd⽂件进⾏验证。如果不指定这个.dtd⽂件,那么会从互联⽹上⾯下载.dtd⽂件,性能不好。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。