8

我很难弄清楚如何处理这个问题:

我正在为一所意大利大学开发一个网络工具,我必须显示带有重音的单词(例如 è、ù、...);有时我从 PostgreSql 表(UTF8 编码)中得到这些词,但大多数情况下我必须从文件中读取长段落。这些文件被编码为 utf-8 xml,并在 Smultron 或任何 utf-8 编辑器中显示良好(它们是在 python 旧文件中使用实体è而不是“è”来解析创建的)。

我编写了一个 java 类,它从 xml 文件中提取相关段,它的工作原理如下:

String s = parseText(filename, position)

如果我将返回的字符串写入文件,一切看起来都很好;问题是,如果我这样做

out.write(s)

在 jsp 页面中,我得到了奇怪的字符。顺便说一句,我用

String s = getWordFromPostgresql(...)

out.write(s)

在同一个jsp中,它显示OK。

有什么提示吗?

谢谢尼古拉


@克罗森沃尔德

感谢您的回复,但是该指令已经在页面中,但它不起作用(实际上它“起作用”但仅适用于我从数据库中获取的字符串)。我认为从文件中读取有些东西,但我无法理解......它们在“java”中工作但不在“jsp”中(想不出更好的解释......)

这是从实际代码中提取的一个基本示例:从文件中读取的方法返回一个 Map,从 Mark(表示文本中位置的对象)到 String(包含文本):

这是在 .jsp 页面中(上面的帖子中引用了 utf 指令)

    // ...
    Map<Mark, String> map = TestoMarkParser.parseMarks(...);
    out.write(map.get(m));

这是结果:

“Fu per√≤ cos√¨ in uso il Genere Enharmonico, che quelli quali vi si esercitavano”

如果我将相同的代码放在 java 类中,并用 System.out.println 替换 out.write,结果是这样的:

“Fu però così in uso il Genere Enharmonico, che quelli quali vi si esercitavano”


我一直在用十六进制编辑器做一些分析,这里是:

原始字符串:“fu però così”

ò 在 xml 文件中:C3 B2

ò 由 jsp 文件中的 out.write() 呈现:E2 88 9A E2 89 A4

ò 通过以下方式写入文件:

FileWriter w = new FileWriter(new File("out.txt"));
w.write(s);     // s is the parsed string
w.close();

C3 B2

将每个字符的值打印为 int

0: 70 = F
1: 117 = u
2: 32 =  
3: 112 = p
4: 101 = e
5: 114 = r
6: 8730 = � 
7: 8804 = � 
8: 32 =  
9: 99 = c
10: 111 = o
11: 115 = s
12: 8730 = �
13: 168 = �
14: 10 = `
4

4 回答 4

15

在 jsp 页面指令中,您应该尝试将内容类型设置为 utf-8,这也会将 pageEncoding 设置为 utf-8。

<%@page contentType="text/html;charset=UTF-8"%>

UTF-8不是jsp 中的默认内容类型,因此会产生各种有趣的问题。问题是底层流默认被解释为 ISO-8859-1 流。如果您将一些 unicode 字节写入此流,它们将被解释为 ISO-8859-1。我发现将编码设置为 utf-8 是最好的解决方案。

编辑:此外,java中的字符串变量应该始终是unicode。所以你应该总是可以说

System.out.println(myString) 

并在您的网络服务器的控制台窗口中查看正确的字符集(或者只是在调试器中停止并检查它)。我怀疑当你这样做时你会看到不正确的字符,这让我相信你在构造字符串时遇到了编码问题。

于 2009-01-28T17:06:23.230 回答
5

我有一些国际 jsp [它们具有“特殊”国际(相对于英语)字符]。

在它们的顶部插入这个 [并且只有这个,即:也没有 contentType 指令(导致重复的 contentType 错误)] 可以让它们正确保存和呈现:

<%@page pageEncoding="UTF-8"%>

这个参考 [http://www.inter-locale.com/codeset1.jsp] 帮助我发现了这一点。

于 2013-03-19T20:07:45.773 回答
0
String s = parseText(filename, position)

这个方法在哪里定义?我猜这是您自己的方法,它打开文件并提取特定的数据块。在这个过程中的某个地方,它正在从字节转换为字符,可能使用 JVM 的默认编码。

如果您正在运行的 JVM 的默认编码与文件中的实际编码不匹配,那么您将在字符串中得到不正确的字符。除此之外,如果您正在阅读以多字节形式(例如 UTF-8)编码的内容,您的“位置”可能指向多字节编码的中间。

如果源文件是格式良好的 XML,那么最好使用真正的解析器(例如 JDK 中内置的解析器)来解析它们,因为解析器会提供正确的字节到字符的转换。然后使用 XPath 表达式检索值。

如果您过去没有使用过 XML 解析器,这里有两个我写的关于解析XPath的文档。


编辑:您可能会发现有用的一件事是使用以下内容打印出字符串中的实际字符值:

public static void main(String[] argv) throws Exception
{
    String s = "testing\u20ac";
    for (int ii = 0 ; ii < s.length() ; ii++)
    {
        System.out.println(ii + ": " + (int)s.charAt(ii) + " = " + s.charAt(ii));
    }
}

您可能还应该打印出您的默认字符集,以便您知道任何特定的字节序列是如何转换为字符的:

public static void main(String[] argv) throws Exception
{
    System.out.println(Charset.defaultCharset());
}

最后,您应该将服务页面作为原始字节进行检查,以准确查看返回给客户端的内容。


编辑#2:字符ò是Unicode值00F2,它将被UTF-8编码为C3 B2。这两个代码与您在之前的答案中显示的符号不对应。

有关 Unicode 字符的更多信息,请参阅 Unicode.org 上的代码表

于 2009-01-28T18:07:08.333 回答
0

我也有同样的问题,一切都是“utf-8”,为什么我看到
无意义的字符,问题出在 jsp 中,它必须在页面的开头。

 <%request.setCharacterEncoding("utf-8");%>

一切都会好起来的。

于 2013-05-26T10:33:24.420 回答