用dom或者sax解析xml运行出现错误Content is not allowed in prolog.
原因及其解决办法:
1.xml编码错误
该xml是UTF-8编码的,如果该文件通过UltraEdit编辑后,会在无BOM头的UTF-8文件中加入BOM,但是DOM4j不认这个BOM(dom4j1.3),解决的办法可以通过升级dom4j到1.6解决www.dom4j.org
什么是BOM?http://www.unicode.org/faq/utf_bom.html#22
Unicode规范中有一个BOM的概念。BOM——Byte Order Mark,就是字节序标记。在这里找到一段关于BOM的说明:
在UCS 编码中有一个叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的编码是FEFF。而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前,先传输字符"ZERO WIDTH
NO-BREAK SPACE"。这样如果接收者收到FEFF,就表明这个字节流是Big-Endian的;如果收到FFFE,就表明这个字节流是Little-Endian的。因此字符"ZERO WIDTH NO-BREAK
SPACE"又被称作BOM。
UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。字符"ZERO WIDTH NO-BREAK
SPACE"的UTF-8编码是EF BB BF。所以如果接收者收到以EF BB BF开头的字节流,就知道这是UTF-8编码了。
Windows就是使用BOM来标记文本文件的编码方式的。
2.xml文件存在非法字符
前两天刚发了一篇关于Resin3下Spring的启动问题的文章(在Resin3下配置SpringSide的HelloWorld示例程序碰到的问题和解决方法),我把持久层框架换成iBATIS后又出现了解析SqlMap文件的新问题,并且花了很长时间才找到解决方法(也可能是我了解的太少,还要加强修炼,呵呵),不管怎么样还是写出来和大家分享,希望对大家有所帮助。
Struts+Spring+Hibernate是目前J2EE企业级开发绝对Killer级的框架组合,相当轻量,优雅,但毫不影响它的强大。虽然因为现在各种表示层框架发展异常活跃,Struts受到了前所未有的挑战和冲击,但是就目前使用面而言这三种框架的组合是JAVA程序员不得不深入的经典。他们相关的资料也比较多,实际运用中也最成熟。但是诸如JSF,iBATIS等后起之秀(说他们后起并不代表他们的历史,只是流行程度)也渐渐的占据自己的一席之地成为某些场合下开发的不二选择。在web服务器方面也是一样,除了Tomcat我们还有了更多好的选择(Resin ,Jetty等)。虽然各种框架都声称自己可以无缝集成各种其他框架,不需要任何修改运行在各种服务器上面,但是我在我最近的一些经验发现把一些平时比较少组合在一起的东西放在一起后确实存在很多想不到的意外,排除起来也颇费一些周折。这可能也是开源和商业的差距,不完善的文档,没有足够覆盖面和严格的测试等,不过我们都要以一个宽容的态度对待开源,因为开源需要我们每个人的参与和贡献,从而真正达到Richard.
M. Stallman心中的软件自由。
我会不断的把在各种非常用的组合使用中遇到的的问题贴出来与大家分享,总有人会需要,呵呵。
言归正传,今天的主题是在Resin3下使用Spring和iBATIS的组合开发时碰到的SqlMap文件解析问题,和开头提到的我的另一篇文章一样,也是一个xml配置文件的解析问题。使用的仍然是SpringSide的HelloWorld示例,这里顺便说个题外话SpringSide是一个我比较欣赏和推荐的国人自己打造的企业级快速开发框架,特别是他的wiki真是一个非常好的各种相关技术的学习资料,但是他发布的示例中含有不少的错误,特别是“非主流的”(非Tomcat下,iBATIS等)模式下有很多问题,希望SpringSide的大侠们能够更加完善。我是你们忠实的支持者。
上篇文章 中提到了Resin3下使用Spring必须要更换默认的xml解析器,换成xerces后就可以正常启动了,然后把持久层框架由Hibernate换为iBATIS后又出现了新的问题,启动时一切正常,Spring和Struts的初始化都没有问题,但是当第一次需要连接数据库时就出现了问题,因为这个时候需要解析SqlMap文件来提供对应的Sql语句进行查询RDB,从异常信息来判断问题出在文件解析的时候,错误信息如下(因为很长,所以只贴了最底层的异常):
1Caused by:
2org.xml.sax.SAXParseException: Content is not allowed in prolog.
3 at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
4 at org.apache.xerces.util.ErrorHandlerWrapper.fatalError(Unknown Source)
5 at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
6 at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
7 at org.apache.xerces.impl.XMLScanner.reportFatalError(Unknown Source)
8 at org.apache.xerces.impl.XMLDocumentScannerImpl$PrologDispatcher.dispatch(Unknown Source)
9 at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
10 at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
11 at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
12 at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
13 at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
14 at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
15 at com.ibatis.common.xml.NodeletParser.createDocument(NodeletParser.java:150)
16 at com.ibatis.common.xml.NodeletParser.parse(NodeletParser.java:50)
17 at com.ibatis.sqlmap.engine.builder.xml.SqlMapParser.parse(SqlMapParser.java:45)
18 at com.ibatis.sqlmap.engine.builder.xml.SqlMapConfigParser$11.process(SqlMapConfigParser.java:347)
19 at com.ibatis.common.xml.NodeletParser.processNodelet(NodeletParser.java:112)
20 at com.ibatis.common.xml.NodeletParser.process(NodeletParser.java:75)
21 at com.ibatis.common.xml.NodeletParser.process(NodeletParser.java:93)
22 at com.ibatis.common.xml.NodeletParser.parse(NodeletParser.java:63)
23 at com.ibatis.common.xml.NodeletParser.parse(NodeletParser.java:51)
24 at com.ibatis.sqlmap.engine.builder.xml.SqlMapConfigParser.parse(SqlMapConfigParser.java:78)
25 at com.ibatis.sqlmap.client.SqlMapClientBuilder.buildSqlMapClient(SqlMapClientBuilder.java:62)
26 at org.springframework.orm.ibatis.SqlMapClientFactoryBean.afterPropertiesSet(SqlMapClientFactoryBean.java:255)
27 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1062)
28 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1029)
29 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:420)
30 at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:245)
31 at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:141)
32 at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:242)
33 at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:156)
34 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByName(AbstractAutowireCapableBeanFactory.java:749)
35 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:704)
36 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:416)
37 at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:245)
38 at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:141)
39 at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:242)
40 at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:223)
41 at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:156)
42 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireByName(AbstractAutowireCapableBeanFactory.java:749)
43 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:704)
44 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:416)
45 at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:245)
46 at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:141)
47 at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:242)
48