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 ...
随机推荐
- 【emWin】例程四:显示文本
实验指导书及代码包下载: http://pan.baidu.com/s/1jHOYdqm
- socket - socketserver - start TCP server
前面提到如何使用socket模块启动tcpserver: 创建socket:sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 绑定ip: ...
- PHP 使用 mcrypt 扩展中的 mcrypt_encrypt() 和 mcrypt_decrypt() 对数据进行加密和解密
<?php /* 使用 mcrypt 扩展中的 mcrypt_encrypt() 和 mcrypt_decrypt() 对数据进行加密和解密 */ // 加密 $algorithm = MCRY ...
- Update Request
public function update(UpdateAppointmentRequest $request) { try { $data = array_filter($request-> ...
- LeakCanary 内存检测 工具 --超级傻瓜 不会DDMS的福音
大神资料贴出 ,学习 ,集成到项目中 . LeakCanary 中文使用说明 http://www.liaohuqiu.net/cn/posts/leak-canary/ logcat 显示 ...
- Quoit Design---hdu1007(最近点对问题 分治法)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1007 题意:给你n(2<=n<=10^6)个点的坐标,然后找到两个点使得他们之间的距离最小 ...
- form 提交数组的一些trick
在给服务器传值时form利用 $.post( "/member/member/book/" + event_id, { tickets: tickets, csrf_ppw_tok ...
- OpenCV2计算机编程手册(一)操作像素
1. 引言 从根本上来说,一张图像是一个由数值组成的矩阵.这也是opencv中使用 代表黑色,代表白色.对于彩色图像(BGR三通道)而言,每个像素需要三个这样的8位无符号数来表示,这种情况下,矩阵的元 ...
- window虚拟机安装Linux
Linux是一种自由和开放源码的类Unix操作系统,存在着许多不同的Linux版本,但它们都使用了Linux内核.Linux可安装在各种计算机硬件设备中,比如手机.平板电脑.路由器.视频游戏控制台.台 ...
- lintcode bugfree and good codestyle note
2016.12.4, 366 http://www.lintcode.com/en/problem/fibonacci/ 一刷使用递归算法,超时.二刷使用九章算术的算法,就是滚动指针的思路,以前写py ...