浏览 2482 次
锁定老帖子 主题:Spring,Struts的DTD验证
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-10-12
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> 当我们用DOM或者Digester来解析这个XML的时候,如果当前计算机已联网那么解析的速度比较慢,如果当前计算机未联网则会报无法连接主机 的异常。这是因为XML的解析器需要读取dtd的内容,而这个dtd文件是存在于互联网的某台主机上的. [曾经因为ibatis的服务器访问不到,总提示找不到dtd验证,苦恼了很久,这回好好研究] 让我们看看开源框架是如何验证DTD的: Spring如何解析网络和本地dtd配置的路径. /** * EntityResolver implementation for the Spring beans DTD, * to load the DTD from the Spring class path (or JAR file). * * <p>Fetches "spring-beans-2.0.dtd" from the class path resource * "/org/springframework/beans/factory/xml/spring-beans-2.0.dtd", * no matter whether specified as some local URL that includes "spring-beans" * in the DTD name or as "http://www.springframework.org/dtd/spring-beans-2.0.dtd". * * @author Juergen Hoeller * @author Colin Sampaleanu * @since 04.06.2003 * @see ResourceEntityResolver */ 以上是类的说明就不贴整段了,免得大家看着烦,我也是. 配置dtd从源代码路径,不管是否有特殊的本地url包含spring-beans.dtd的名称 ,实际还是从本地取DTD路径.[ XML配置还是以网络地址显示],这也是为什么即使Spring在没有网络连接的情况下还是依然可以运行. 那么这是怎么查找指定的,请看如下代码: public InputSource resolveEntity(String publicId, String systemId) 通过publicId和systemId. 比如: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" " http://www.springframework.org/dtd/spring-beans.dtd "> 其PublicID就是-//SPRING//DTD BEAN//EN. 其 SystemID就是- http://www.springframework.org/dtd/spring-beans.dtd. 在Spring框架中只要你使用标准的xml dtd或者schema声名,就会自动从spring.jar里面加载到dtd或schema.其加载程序如下. Resource resource = new ClassPathResource(dtdFile, getClass()); InputSource source = new InputSource(resource.getInputStream()); source.setPublicId(publicId); source.setSystemId(systemId); 这里的路径就是相对于此BeansDtdResolver的路径,也就是org.springframework.beans.factory.xml,所以Spring的dtd等配置文件放在这个目录下,没有网络照样运行. 接下来让我们看下Struts是如何加载dtd文件的. 看Struts源码如下: protected String[] registrations = { "-//Apache Software Foundation//DTD Struts Configuration 1.0//EN", "/org/apache/struts/resources/struts-config_1_0.dtd", "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN", "/org/apache/struts/resources/struts-config_1_1.dtd", "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN", "/org/apache/struts/resources/struts-config_1_2.dtd", "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN", "/org/apache/struts/resources/struts-config_1_3.dtd", "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN", "/org/apache/struts/resources/web-app_2_3.dtd" }; publicID直接写死,systemId直接写死.哈哈,与Spring对比,Spring的publicId由xml动态指定,如果需要添加dtd或schema版本等不需要修改代码,Struts必须修改代码,或许大家也看到差距了,感觉Struts1.X都很久没更久了,曾经的辉煌都被埋没了.[不知道哪种利益驱动了,搞了个struts2.x,完全不同的理念] // Create a new Digester instance with standard capabilities configDigester = new Digester(); configDigester.setNamespaceAware(true); configDigester.setValidating(this.isValidating()); configDigester.setUseContextClassLoader(true); configDigester.addRuleSet(new ConfigRuleSet()); for (int i = 0; i < registrations.length; i += 2) { URL url = this.getClass().getResource(registrations[i + 1]); if (url != null) { configDigester.register(registrations[i], url.toString()); } } this.addRuleSets(); Struts是使用Digester进行dtd的注册,现在终于明白了,为什么Struts和Spring在没有网络的情况下可以运行,但是有的外部包,在没有网络的情况下,或者网络有问题的时候会出问题,这也是我们要注意的,在引入其他项目时,配置文件中的dtd是必须要关注的,在本地开发完全正常,到没有网络环境的时候,你就傻眼了. 解决Dtd问题也是我们平时开发必须考虑的. 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |