mybatis,Spring等工具对xml文件正确性的验证
我们知道mybatis或者spring都是使用xml文件作为配置文件,配置文件的格式都是定义在叫做.dtd或者.xsd文件中的,当工具在解析用户自己定义的xml文件的时候,如何才能知道用户自定义的文件是否正确的呢?我们不能在xml文件中乱写一些框架不认识的标签,比如在spring的xml文件中写如下<user>标签,毫无疑问会报错。那么框架是怎么来验证我们所写的标签是否正确的呢?
<user>
<id>100</id>
</user>
由于mybatis使用的是dom解析,利用JDK的dom解析API,如下:
@Test
public void docFactoryTest() throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(true);
factory.setNamespaceAware(false);
factory.setIgnoringComments(true);
factory.setIgnoringElementContentWhitespace(false);
factory.setCoalescing(false);
factory.setExpandEntityReferences(true);
DocumentBuilder builder = factory.newDocumentBuilder();
builder.setEntityResolver(new XMLMapperEntityResolver());
...(此处省略一部分代码)
Document doc = builder.parse(Resources.getResourceAsStream("mybatis-config.xml"));
System.err.println(doc);
在第11行中,用到了XMLMapperEntityResolver对象,这个对象定义如下:
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;
}
}
可以看到,当框架在解析xml文件的时候,会把xml文件开头的publicId和systemId传给EntityResolver,而EntityResolver对象就是从classpath中去寻找.dtd文件(文件就在org/apache/ibatis/builder/xml/目录下),在spring中还会存在.xsd文件,原理都是一样的,然后利用classpath中的.dtd文件进行验证。如果不指定这个.dtd文件,那么会从互联网上面下载.dtd文件,性能不好。
mybatis,Spring等工具对xml文件正确性的验证的更多相关文章
- mybatis 的 dao 接口跟 xml 文件里面的 sql 是如何建立关系的?一步步解析
序言 在开始正文之前,首先解释Dao接口和XML文件里的SQL是如何一一对应的? 一句话讲完就是:mybatis 会先解析这些xml 文件,通过 xml 文件里面的命名空间 (namespace)跟d ...
- 【报错】spring整合activeMQ,pom.xml文件缺架包,启动报错:Caused by: java.lang.ClassNotFoundException: org.apache.xbean.spring.context.v2.XBeanNamespaceHandler
spring版本:4.3.13 ActiveMq版本:5.15 ======================================================== spring整合act ...
- mybatis 的 dao 接口跟 xml 文件里面的 sql 是如何建立关系的?
mybatis 会先解析这些xml 文件,通过 xml 文件里面的命名空间 (namespace)跟dao 建立关系:然后 xml 中的每段 sql 会有一个id 跟 dao 中的接口进行关联. 那么 ...
- Java 使用poi导入excel,结合xml文件进行数据验证的例子(增加了jar包)
ava 使用poi导入excel,结合xml文件进行数据验证的例子(增加了jar包) 假设现在要做一个通用的导入方法: 要求: 1.xml的只定义数据库表中的column字段,字段类型,是否非空等条件 ...
- Spring介绍及配置(XML文件配置和注解配置)
本节内容: Spring介绍 Spring搭建 Spring概念 Spring配置讲解 使用注解配置Spring 一.Spring介绍 1. 什么是Spring Spring是一个开源框架,Sprin ...
- 【MyBatis学习05】SqlMapConfig.xml文件中的配置总结
经过上两篇博文的总结,对mybatis中的dao开发方法和流程基本掌握了,这一节主要来总结一下mybatis中的全局配置文件SqlMapConfig.xml在开发中的一些常用配置,首先看一下该全局配置 ...
- 【转】Mybatis 3.1中 Mapper XML 文件 的学习详解
MyBatis 真正的力量是在映射语句中.这里是奇迹发生的地方.对于所有的力量,SQL 映射的 XML 文件是相当的简单.当然如果你将它们和对等功能的 JDBC 代码来比较,你会发现映射文件节省了大约 ...
- Spring MVC 配置文件dispatcher-servlet.xml 文件详解
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- Spring MVC 配置文件dispatcher-servlet.xml 文件详解(转自 学无止境-yj)
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
随机推荐
- PHPExcel中文开发手册翻译版(2)
2016年8月18日12:45:14 请注意这个是粗翻译版,仅供参考,不是精校版 精校版后面才会更新 PHPExcel开发者文档 1.目录 2. 4先决条件 2.1.软件要求4 2.2.安装说明4 2 ...
- Log4Net
注意事项 <!-- The file log4Net.config is copied into bin/Debug /release by compiler 添加如下内容到 assemblyi ...
- Sina 新浪Ip归属地Api 很好用的,使用get请求
前言 这几天做了一个客服管理系统,需要根据游客的Ip获取他的归属地,刚开始使用了,www.ip138.com 抓取ip归属地,用这还可以,但是不显示国家:于是是找了这个新浪的Api,很不错啊 用法 1 ...
- 【Android测试】Android截图的深水区
◆版权声明:本文出自胖喵~的博客,转载必须注明出处. 转载请注明出处:http://www.cnblogs.com/by-dream/p/6113059.html 需求 这两天遇到这样一个事情,因为某 ...
- jquery的$().each,$.each的区别
在jquery中,遍历对象和数组,经常会用到$().each和$.each(),两个方法.两个方法是有区别的,从而这两个方法在针对不同的操作上,显示了各自的特点. $().each,对于这个方法,在d ...
- macOS sierra 10.12 Cocoapods 私有库
使用Cocoapods创建私有podspec 见文章:http://www.cocoachina.com/ios/20150228/11206.html 或http://blog.wtlucky.co ...
- oracle 函数调用
--带out的函数 create or replace function fun_try(v_name varchar,v_outname out varchar)return varchar2 is ...
- Java反射使用技巧
1. 通过setAccessible关闭安全检查,关闭的目的不是因为访问的field/method是私有的,而且因为关闭后访问公有方法也不会再有安全检查. SomeObject someObject ...
- cocos2d-x 运行时xcode提示错误:"vtable for XXX", referenced from 问题已解决;
vtable/引用和虚函数相关,今天在添加一个层的时候报了这个错误,很低级的错误,忘了实现虚函数了(谨记!!) 若如果实现了虚函数还依然如此的话,可能是创建的时候忘了钩上 -desktop 选项了,把 ...
- java.util.ConcurrentModificationException --map
key:3-key key:/v1.02-key Exception in thread "main" java.util.ConcurrentModificationExcept ...