utf 8 charset不适用于javax邮件

时间:2013-02-23 18:28:45

标签: java utf-8 character-encoding javamail

我使用Javax Mail API发送电子邮件。我使用联系方式发送输入,必须将其发送到特定的电子邮件。

发送电子邮件没有问题,虽然我是一个丹麦人,因此我需要三个丹麦字符,即'æ','ø'和'å',在主题和电子邮件文本中。< / p>

因此我看到我可以使用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);
}

请帮我看看如何纠正这个'错误'。

6 个答案:

答案 0 :(得分:68)

对于所有电子邮件

有几个system properties related to mailing,可能会简化您的代码。我实际上是在讨论这个特定的属性:"mail.mime.charset"

  

可以使用 mail.mime.charset 系统属性指定默认MIME字符集,以用于编码字和文本部分,否则不会指定字符集。通常,默认MIME字符集是从file.encoding System属性中指定的默认Java字符集派生的。大多数应用程序不需要显式设置默认MIME字符集。如果要用于邮件消息的默认MIME字符集与用于存储在系统上的文件的字符集不同,则应设置此属性。

如上所述,默认情况下,mail.mime.charset没有值,并且使用了文件编码(file.encoding属性)。

对于特定的电子邮件

但是,如果要为特定电子邮件指定特定编码,则应该使用2参数setSubject(subject,charset)setText(text,charset)方法。

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

Mime类型很复杂

setContent(content, "UTF-8")(正如其他来源声明的那样)将无效。只需查看此方法的签名:setContent(Object content, String mimetype) Mime类型和字符集是两个完全不同的东西。 Imho,你应该使用charset参数中的一个setText(...)方法。

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

  • RFC-2046中所述,text/plain的默认字符集为US-ASCII,但可以使用其他字符集参数进行否决。
  • 但是,在RFC-6657中明确指出text/xml类型使用邮件内容确定字符集。 此处将忽略charset参数。
  • RFC-2854中声明text/html应该总是指定一个字符集。但如果你不这样做,那么它将使用ISO-8859-1(= Latin-1)。

答案 1 :(得分:30)

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

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

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

答案 2 :(得分:6)

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

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

解决方案似乎在我的部署描述符中设置了一个字符编码过滤器,它会将来自Web的所有传入请求编码为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'/ *'的所有请求。

答案 3 :(得分:0)

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

答案 4 :(得分: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”),整个过程就正常了。

答案 5 :(得分:0)

在将 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");

This is the result in Spanish.