62

我使用Java Mail API来发送电子邮件。我正在使用联系人公式发送输入,该输入必须发送到特定的电子邮件。

尽管我是丹麦人,但电子邮件发送没有问题,因此我需要三个丹麦字符,即主题和电子邮件文本中的“æ”、“ø”和“å”。

因此,我看到我可以使用 UTF-8 字符编码来提供这些字符,但是当我发送邮件时,我只看到一些奇怪的字母 - 'ã¦'、'ã¸' 和 'ã¥' - 而不是丹麦字母 - 'æ'、'ø' 和 'å'。

我发送电子邮件的方法如下所示:

public void sendEmail(String name, String fromEmail, String subject, String message) throws AddressException, MessagingException, UnsupportedEncodingException, SendFailedException
{
    //Set Mail properties
    Properties props = System.getProperties();
    props.setProperty("mail.smtp.starttls.enable", "true");
    props.setProperty("mail.smtp.host", "smtp.gmail.com");
    props.setProperty("mail.smtp.socketFactory.port", "465");
    props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
    props.setProperty("mail.smtp.auth", "true");
    props.setProperty("mail.smtp.port", "465");
    Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {
        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication("my_username", "my_password");
        }
    });

    //Create the email with variable input
    MimeMessage mimeMessage = new MimeMessage(session);
    mimeMessage.setHeader("Content-Type", "text/plain; charset=UTF-8");
    mimeMessage.setFrom(new InternetAddress(fromEmail, name));
    mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress("my_email"));
    mimeMessage.setSubject(subject, "utf-8");
    mimeMessage.setContent(message, "text/plain");

    //Send the email
    Transport.send(mimeMessage);
}

请帮助我找出如何纠正这个“错误”。

4

7 回答 7

98

对于所有电子邮件

有几个与 mailing 相关的系统属性,可以简化您的代码。我实际上是在谈论这个特定的属性:"mail.mime.charset".

mail.mime.charsetSystem 属性可用于指定默认 MIME 字符集以用于未指定字符集的编码单词和文本部分。通常,默认 MIME 字符集派生自默认 Java 字符集,如file.encodingSystem 属性中指定的那样。大多数应用程序无需显式设置默认 MIME 字符集。如果用于邮件消息的默认 MIME 字符集与用于存储在系统上的文件的字符集不同,则应设置此属性。

正如您在上面所读到的,默认情况下没有值,mail.mime.charset并且使用文件编码(file.encoding属性)。

对于特定的电子邮件

但是,如果您想为特定的电子邮件指定特定的编码,那么您可能应该使用 2 参数setSubject(subject,charset)setText(text,charset)方法。

如果这不起作用,那么您的输入可能在达到这一点之前已经损坏。换句话说,您可能使用了错误的编码来收集您的数据

哑剧类型很复杂

(正如其他消息来源声称的setContent(content, "UTF-8")那样)将不起作用。看看这个方法的签名:setContent(Object content, String mimetype). Mime 类型和字符集是两个完全不同的东西。恕我直言,您真的应该使用其中一种setText(...)带有 charset 参数的方法。

但是,如果您坚持使用 mimetype 来设置 charset setContent(content,mimetype),那么请使用正确的格式。(不仅仅是"UTF-8",而是类似的东西"text/plain; charset=UTF-8")。但更重要的是,请注意每种 mime 类型都有自己处理字符集的方式。

  • RFC-2046中所述,默认字符集为text/plainUS-ASCII但可以使用附加的字符集参数否决。
  • 但是,在RFC-6657中明确指出,text/xml类型使用消息的内容来确定字符集。charset 参数将在这里被忽略。
  • 并且在RFC-2854中声明text/html应该始终指定一个字符集。但如果你不这样做,那么它将使用ISO-8859-1(= Latin-1)。
于 2014-12-10T15:33:19.613 回答
51

也许你也应该在这里提供 UTF-8

mimeMessage.setContent(message, "text/plain; charset=UTF-8");

你必须看看http://www.coderanch.com/t/274480/java/java/JavaMail-set-content-utf

于 2013-02-23T18:33:08.033 回答
8

在花了很多时间进行调试并在互联网上搜索线索后,我找到了解决问题的方法。

似乎每当我通过网络请求发送数据时,我的应用程序都没有使用 UTF-8 编码对字符进行编码。这意味着从我的联系表单发送的包含 æ、ø 和 å 字符的数据无法通过字符编码正确处理。

该解决方案似乎在我的部署描述符中设置了一个字符编码过滤器,它将所有来自网络的传入请求编码为字符编码 UTF-8。

private void registerCharacterEncodingFilter(ServletContext servletContext) {
    CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
    encodingFilter.setEncoding("UTF-8");
    encodingFilter.setForceEncoding(true);
    FilterRegistration.Dynamic characterEncodingFilter = servletContext.addFilter("characterEncodingFilter", encodingFilter);
    characterEncodingFilter.addMappingForUrlPatterns(null, false, "/*");
}

此过滤器将编码设置为 UTF-8,并强制对来自 url ' /* ' 的所有请求进行编码。

于 2013-03-01T20:19:15.933 回答
2

很简单,使用参数 -Dfile.encoding=UTF-8 运行您的项目 例如:java -Dfile.encoding=UTF-8 -jar MyProject.jar

//修正一个错字

于 2013-08-15T10:45:44.430 回答
1

在将您的 String 发送到 send 方法之前,您必须将 String 转换为 UTF-8

如果您收到“请求”参数,则可以使用“setCharacterEncoding”:

request.setCharacterEncoding("utf-8");
String subject = request.getParameter("subject");
String content = request.getParameter("content");
...
MimeMessage mineMessage = new MimeMessage(session);
        mineMessage.setFrom(new InternetAddress(myAccountEmail));
        mineMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(recepient));
        mineMessage.setSubject(subject, "UTF-8");
        mineMessage.setContent(content, "text/plain;charset=UTF-8");

否则,请使用以下方法将您的字符串转换为 UTF-8 格式:

String subject = new String(subject.getBytes(Charset.forName("ISO-8859-1")), Charset.forName("UTF-8"));
String content = new String(content.getBytes(Charset.forName("ISO-8859-1")), Charset.forName("UTF-8"));
...
MimeMessage mineMessage = new MimeMessage(session);
    mineMessage.setFrom(new InternetAddress(myAccountEmail));
    mineMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(recepient));
    mineMessage.setSubject(subject, "UTF-8");
    mineMessage.setContent(content, "plain/plain;charset=UTF-8");

这是西班牙语的结果。

于 2021-07-12T22:00:15.630 回答
0

我知道我迟到了这个问题,但我刚才遇到了类似的问题。

检查您的源编码也可能是值得的!我正在使用一个测试类,其中包含一些特殊字符的硬编码主题/文本,在发送电子邮件时不断出现乱码。即使我在适用的地方设置了字符集 UTF-8 (mimeMessage.setSubject(subject, charset), mimeMessage.setContent(content, "text/plain; charset=UTF-8"))。

然后我注意到这个类的源编码是windows-1252。据我了解,编译 java 文件时,任何源文本都会转换为 UTF-8。但是在这种情况下,在这个项目的 maven pom.xml 中,缺少 project.build.sourceEncoding 属性 - 所以我实际上不确定在编译期间(默认情况下)使用哪个编码 maven,因为没有指定。

在这里更改源编码是不可能的,但是一旦我将特殊字符更改为 Unicode 代码文字(例如“ü”到“\u00fc”),整个事情就很好了。

于 2021-03-19T16:25:02.093 回答
-1
mimeMessage.setContent(mail.getBody(), "text/html; charset=UTF-8");

也许我错了,但这对我有用。:) 任何 ööö、äää、üüü 字符都会在我的前景中正确显示。

展望截图

于 2021-12-17T12:52:56.487 回答