这个问题涉及一个Tomcat 7 Web应用程序,该应用程序连接到MySQL(5.5.16)数据库。
当我打开zip
文件时,其文件名在windows-1252
字符集中编码,字符似乎由Java正确解释:
ZipFile zf = new ZipFile( zipFile, Charset.forName( "windows-1252" ) );
Enumeration entries = zf.entries();
while( entries.hasMoreElements() ) {
ZipEntry ze = ( ZipEntry ) entries.nextElement();
if( ! ze.isDirectory() ) {
String name = ze.getName();
System.out.println( name ); //prints correct filenames, e.g. café.pdf
}
}
在ZipFile构造函数中省略Charset对象会导致异常。 zip文件中的文件名正确打印到标准输出,包括变音符号。 但是,当我随后尝试将文件名存储在数据库中时,e-acute被替换为问号(如mysql控制台客户端所示)。 我以前没有问题从Web应用程序插入特殊字符到MySQL。
当我在Java源代码中执行带é
的INSERT时:
statement.executeUpdate( "insert into files (filename) values ('café.pdf')" );
é
在MySQL中表现得很好。
此外,我的日志文件显示逗号而不是é: caf‚.pfd
有谁知道这里会发生什么?
答案 0 :(得分:1)
正如您在评论部分中提到的,传入数据(压缩文件的名称)可以是不同的字符集。这对您来说是一个问题,因为您使用的是MySQL + JDBC链接,它会给您带来很多限制(例如MySQL中每列一个字符集,JDBC中每个连接只有一个字符集)。 p>
因此,我建议你将MySQL端的字符集(查找character_set_server
和character_set_connection
等变量)切换为UTF8,因为它可以让你传输和存储几乎任何字符你可能会收到。有关如何正确设置MySQL服务器的信息,请参阅here。请注意,MySQL服务器的设置可能具有挑战性,因此请不要犹豫,以获得额外的帮助。 JDBC将自动调整为服务器的character_set_connection
变量,因此您不必更改Java应用程序中的任何内容。
您必须在应用程序中更改的一件事是您必须将所有传入数据转换为UTF8,以便将其发送并存储在MySQL服务器上。
祝你好运。答案 1 :(得分:0)
在存储数据的表格中,请确保使用正确的排序规则以存储电子锐化字符
答案 2 :(得分:0)
问题已解决。 This post建议zip
文件中的文件名编码可能不是windows-1252
,而是IBM437
。更改Charset
:
ZipFile zf = new ZipFile( zipFile, Charset.forName( "windows-1252" ) );
到
ZipFile zf = new ZipFile( zipFile, Charset.forName( "IBM437" ) );
给出了所需的结果:在MySQL中保存获取的文件名时,它与é。
一起正确存储出了什么问题?
使用
将zip文件中包含的文件名打印到标准输出System.out.println( name );
让我错误地认为zip文件中的文件名被解释得很好:当我使用windows-1252
编码打开zip文件时,文件名用diacritic:café.pdf很好地打印到标准输出。使用其他字符编码,出现了不同的符号而不是é。
但是在this answer的帮助下打印é - Unicode
的{{1}}值时,我能够看到用char
编码打开zip文件时,实际的Unicode值不是windows-1252
(带有急性的拉丁小写字母e),而是\u00e9
(单个低9引号)。当我使用\u201a
字符集打开ZipFile
时,会显示正确的Unicode值DID。
当然,使用IBM437
将String
打印到标准输出时,PrintStream
也会与某个字符编码相关联。来自PrintStream
Javadoc:
使用平台的默认字符编码将PrintStream打印的所有字符转换为字节。
我正在使用Windows XP。
当我创建新的PrintStream
PrintStream
一切都有意义:打开带有out = new PrintStream( System.out, true, "IBM437" );
字符编码的zip文件,并使用新的PrintStream,é被正确打印。