“中文问题没商量”之Spring2.0项目中的Bug一例

来源:互联网 发布:开淘宝店用什么笔记本 编辑:程序博客网 时间:2024/05/01 17:25
  Spring是一个非常优秀的开源项目,然而,跟其它任何优秀的系统产品一样,也存在着这样那样的问题,我们喜欢称为Bug。Spring中的Bug确实不少,今天为了充实“中文问题没商量”主题,举一个不算很重要,也比较简单理解的一个Bug示例。
  这里提前申明,这个话题不是针对Spring项目,因此请“春迷”们自重、没事勿扰,文中不足之处欢迎大家批评指教。
  我们知道,一个开源软件项目,给用户的单元测试最基本的要求是能全部通过测试,在Java中就是在运行单元测试的时候应该要看见一个绿条。Spring项目的单元测试写得非常好,也非常全面。然而,单元测试中却有一些问题,在中文路径上无法完全通过测试,必须放到英文路径下才能完全通过测试,因此,这属于一种“没商量”的中文问题。
  单元测试:
  包:org.springframework.beans.factory.xml
  类:XmlBeanFactoryTests
  方法:testFileSystemResourceWithImport
  错误图示:
 


  详细错误信息:
org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from file [C:/Documents%20and%20Settings/Administrator/%e6%a1%8c%e9%9d%a2/spring/spring-framework-2.0-rc2/bin/org/springframework/beans/factory/xml/resource.xml]; nested exception is java.io.FileNotFoundException: C:/Documents%20and%20Settings/Administrator/%e6%a1%8c%e9%9d%a2/spring/spring-framework-2.0-rc2/bin/org/springframework/beans/factory/xml/resource.xml (系统找不到指定的路径。)
Caused by: java.io.FileNotFoundException: C:/Documents%20and%20Settings/Administrator/%e6%a1%8c%e9%9d%a2/spring/spring-framework-2.0-rc2/bin/org/springframework/beans/factory/xml/resource.xml (系统找不到指定的路径。)
 at java.io.FileInputStream.open(Native Method)
 at java.io.FileInputStream.(FileInputStream.java:106)
 at org.springframework.core.io.FileSystemResource.getInputStream(FileSystemResource.java:85)
 at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334)
 at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:315)
 at org.springframework.beans.factory.xml.XmlBeanFactory.(XmlBeanFactory.java:73)
 at org.springframework.beans.factory.xml.XmlBeanFactory.(XmlBeanFactory.java:61)
 at org.springframework.beans.factory.xml.XmlBeanFactoryTests.testFileSystemResourceWithImport(XmlBeanFactoryTests.java:946)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:585)
 at junit.framework.TestCase.runTest(TestCase.java:154)
 at junit.framework.TestCase.runBare(TestCase.java:127)
 at junit.framework.TestResult$1.protect(TestResult.java:106)
 at junit.framework.TestResult.runProtected(TestResult.java:124)
 at junit.framework.TestResult.run(TestResult.java:109)
 at junit.framework.TestCase.run(TestCase.java:118)
 at junit.framework.TestSuite.runTest(TestSuite.java:208)
 at junit.framework.TestSuite.run(TestSuite.java:203)
 at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:128)
 at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)

测试代码:
public void testFileSystemResourceWithImport() {
  String file = getClass().getResource("resource.xml").getFile();
  XmlBeanFactory xbf = new XmlBeanFactory(new FileSystemResource(file));
  // comes from "resourceImport.xml"
  ResourceTestBean resource1 = (ResourceTestBean) xbf.getBean("resource1");
  // comes from "resource.xml"
  ResourceTestBean resource2 = (ResourceTestBean) xbf.getBean("resource2");
 }
 
出错原因:
  这个问题是笔者在参与开发EasyJWeb及EasyDBO框架中遇到过的问题,因此很容易就找到了问题的所在。Java的Class.getResource(name)返回的是一个URL,而URL.getFile默认情况下返回的是经过URL编码后的字符,会把中文等特殊字符变成类似%e6的形式。而一般io构造路径是没有自动解码功能的,所以在中文路径下要出现错误。
 
解决办法:
  在使用URL.getFile返回的路径时,使用前需要使用java.net.URLDecoder对路径进行一次解码操作。修改后的且能通过测试的方法如下:
public void testFileSystemResourceWithImport() {
  String file = getClass().getResource("resource.xml").getFile();
  try{
  file=java.net.URLDecoder.decode(file,"UTF-8");
  }
  catch(Exception e)
  {
   e.printStackTrace();
  } 
  XmlBeanFactory xbf = new XmlBeanFactory(new FileSystemResource(file));
  // comes from "resourceImport.xml"
  ResourceTestBean resource1 = (ResourceTestBean) xbf.getBean("resource1");
  // comes from "resource.xml"
  ResourceTestBean resource2 = (ResourceTestBean) xbf.getBean("resource2");
 }
 
小结:
  由于Spring开源项目的开发团队中,除了一些喜欢跟在Rod大叔的屁股后面唱中文版赞歌的“春迷”以外,当前似乎还没有中国人参与到正式的Spring开发小组中。因此,也许没有在中文路径下运行过测试用例,导致我这样的Spring初学者一不小心就遇上这样的问题。
  问题是解决了,但是却是一种比较罕见的方式,而且Spring开发小组事先也许没有预想到或是故意忽略掉的问题,因此,可以称得上是“没商量”的中文问题。
   (注:本文作者,EasyJF开源团队 大峡,转载请保留作者声明!)
 

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1099389


原创粉丝点击