如何添加对字符集IBM437到J2SE 1.4 API的支持

时间:2011-09-05 07:36:21

标签: java java-ee encoding character-encoding

1 个答案:

答案 0 :(得分:4)

您似乎使用IBM437作为charset的规范名称或别名,并且根据same page that you linked,它未列为有效名称或别名。相反,会列出IBM-437,这似乎是正确的名称,您应该指定它。

我没有看到问题中发布的任何代码,它在代码中使用字符串文字IBM437,并且通过堆栈跟踪我怀疑你已经在JSP中指定了它(它被编译成一个使用Jasper引擎的Servlet,可以在pageEncoding属性中,也可以在contentType指令的page属性中。所以,你应该在JSP中将IBM437替换为IBM-437,并重新编译它。

此外,您尚未指定项目是否必须使用IBM-437字符集。我怀疑正在使用IBM-437字符集,因为有一个或多个系统属性设置为file.encoding IBM-437。如果您不打算使用IBM-437,那么您应该开始考虑在整个代码中使用规范名称或别名(如UTF-8),这样您的应用程序就输入的字符集没有任何错误的假设它正在处理的数据或输出响应。


更新回答

根据新的堆栈跟踪和发布的代码,可以推断出以下内容:

  • 您正在使用TrueZIP 6.这在某种程度上很重要,因为在您的JRE中需要IBM437字符集支持的根本原因是由underlying requirement of encoding file entries in a ZIP file using the IBM437 character set引起的,也称为{{1} }。
  • 您当前的JRE和操作环境不支持任何格式的CP437字符集 。请注意前一行中的重点。显然,TrueZIP 6支持IBM437,即使JRE可能不支持此字符集。 TrueZIP使用SPI provider concept in Java NIO that is available since Java 1.4来支持JRE本身不支持的其他字符集;在这种特殊情况下,IBM437字符集通过必须存在于truezip-6.jar文件中的IBM437类来支持。 JAR文件还必须包含以下文件:de.schlichtherle.nio.charset.IBM437Charset,内容为META-INF/services/java.nio.charset.spi.CharsetProvider(即TrueZIP中嵌入的charset提供程序,用于注册de.schlichtherle.nio.charset.spi.CharsetProvider类)。

基于以上所述,您应该验证以下内容:

  • Web应用程序的类加载器是否可以查找TrueZIP中嵌入的charset提供程序?这很重要,因为底层JRE(我假设它是Sun JRE 1.4.2_x)不支持IBM437Charset字符集,而TrueZIP依赖嵌入式字符集提供程序来支持IBM437字符集。因为,使用当前线程的上下文类加载器查找IBM437 s(在CharsetProvider Java API文档中注明),无法加载TrueZIP的CharsetProvider将导致CharsetProvider被抛出。在大多数Web应用程序中,当前线程的上下文类加载器也恰好是Web应用程序的类加载器(从InconsistentCharsetSupportErrorWEB-INF\lib加载类),但这不一定是真的。如果上下文类加载器不是Web应用程序类加载器,则必须将WEB-INF\classes文件放在上下文类加载器的类路径中,而不是WEB-INF \ lib。
  • 您可以通过在独立的JRE(来自命令行)中运行代码而不是在Web应用程序中运行代码来验证错误是否与加载TrueZIP truezip-6.jar实现有关;记得将truezip-6.jar放在应用程序的类路径中。
  • 考虑将truezip-6.jar放在Web应用程序容器使用的JRE的扩展目录(CharsetProvider)中。只有当您无法获取当前线程的上下文类加载器才能加载TrueZIP <jre>/lib/ext时,并且只有在您确认问题与加载CharsetProvider时才应该尝试。