从数据库到javamail的编码问题

时间:2011-01-13 12:58:54

标签: java oracle encoding javamail

我有一个小应用程序,它从Oracle 9i数据库读取并使用JavaMail通过电子邮件发送数据。数据库有NLS_CHARACTERSET = "WE8MSWIN1252",就是它,CP1252。

如果我在没有任何参数的情况下运行应用程序,它可以正常工作并正确发送电子邮件。但是,我有一个强制要求我使用-Dfile-encoding=utf8参数运行应用程序,这会导致文本发送时出现损坏的字符。

我尝试使用以下命令更改从数据库读取的数据的编码:

String textToSend = new String(textRead.getBytes("CP1252"), "UTF-8");

但它没有帮助。我已尝试使用CP1252, windows-1252, ISO-8859-1UTF-8的所有可能组合,但仍然没有运气。

有什么想法吗?


更新以澄清我的问题:当我执行以下操作时:

Statement stat = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
stat.executeQuery("SELECT blah FROM blahblah ...");
ResultSet rs = stat.getResultSet();
String textRead = rs.getString("whatever");

我的textRead已损坏,因为数据库是CP1252,应用程序以UTF-8运行。我尝试过的另一种方法也失败了:

InputStream is = rs.getBinaryStream("whatever");
Writer writer = new StringWriter();
char[] buffer = new char[1024];
Reader reader = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
while ((n = reader.read(buffer)) != -1) {
    writer.write(buffer, 0, n);
}
String textRead = writer.toString();

5 个答案:

答案 0 :(得分:2)

您的驱动程序应自动执行转换,因为cp-1252是UTF-8的子集,所以您不应丢失信息。

您可以尝试以下操作:使用ResultSet.getString获取字符串,将字符串写入文件。使用编辑器打开文件,您可以使用该编辑器指定UTF-8字符集(例如jEdit)。

该文件应包含UTF-8数据。

答案 1 :(得分:1)

你似乎迷失在charset空间 - 我理解这一点...... :-)

这一行

String textToSend = new String(textRead.getBytes("CP1252"), "UTF-8");

没有多大意义。您已经有文本,将其转换为“cp1252”编码的字节[]。然后你告诉VM将字节视为“UTF-8”(这是谎言......)。

简而言之:如果你在 textRead 中有一个字符串,则根本不需要转换它。如果出现问题,文本已经腐烂(在调试器中查看)或稍后在API中腐烂。检查一下,并回来更详细一点?错误的文本在哪里以及您从哪里读取或写入...

答案 2 :(得分:1)

您的数据库数据位于windows-1252。所以 - 假设它被JDBC驱动程序逐字递回 - 当你尝试将它转换为Java String那个你需要指定的字符集:

Statement stat = connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet rs = stat.executeQuery("SELECT blah FROM blahblah ...");
byte[] rawbytes = rs.getBytes("whatever");
String textRead = new String(rawbytes, "windows-1252");

是否要求将数据邮寄为UTF-8?如果是这样,UTF-8部分需要出现在输出端,而不是输入端。当您在Java中有String数据时,它在内部存储为UTF-16。因此,当您将其序列化为MimeMessage时,您再次需要选择一个字符集:

mimebodypart.setText(textRead, "UTF-8");

答案 3 :(得分:1)

我遇到了同样的问题:

Orace数据库使用WE8MSWIN1252字符集,一些包含欧元符号(€)的VARCHAR2列数据/文本。使用JavaMail发送文本会给欧元符号带来问题。

最后它有效。你应该检查/做的两件重要事情:

  • 请确保为您使用的Java版本使用最新的Oracle JDBC驱动程序。
  • 在JavaMail中指定charset(prefer:UTF-8),例如

    由MimeMessage.setSubject(String text,“UTF-8”)
    MimeMessage.setText(String text,“ UTF-8“)。

    这样,电子邮件文本就会被UTF-8编码。

    注意:因为RFC 821将邮件限制为7位US-ASCII,8位字符或二进制数据需要编码为7位格式。电子邮件标题“Content-Transfer-Encoding”指定使用的编码。有关详细信息:http://www.w3.org/Protocols/rfc1341/5_Content-Transfer-Encoding.html

答案 4 :(得分:0)

您可以在数据库中进行转换吗?而不是:

SELECT blah FROM blahblah

尝试

SELECT convert(blah, 'WE8MSWIN1252', 'UTF8') FROM blahblah