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小时内删除。
发表评论