ti-enxame.com

utf 8 charset não funciona com o javax mail

Eu usei o Javax Mail API para enviar e-mails. Estou usando um formulário de contato para enviar a entrada, que deve ser enviada para um email específico.

O e-mail é enviado sem problemas, embora eu seja um cara dinamarquês, e estou, portanto, precisando de três caracteres dinamarqueses, que é 'æ', 'ø' e 'å', no assunto e no texto do e-mail.

Por isso, vi que posso usar a codificação de caracteres UTF-8 para fornecer esses caracteres, mas quando meu e-mail é enviado, vejo apenas algumas letras estranhas - 'ã¦', 'ã¸' e 'ã ¥' - em vez de letras dinamarquesas - 'æ', 'ø' e 'å'.

Meu método para enviar o e-mail está parecendo assim

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);
}

Por favor me ajude a descobrir como posso corrigir esse 'erro'.

41
Rohwedder

Para todos os e-mails

Existem algumas propriedades do sistema relacionadas ao envio de mensagens , que provavelmente podem simplificar seu código. Eu estou falando sobre essa propriedade específica, na verdade: "mail.mime.charset".

A propriedade de sistema mail.mime.charset pode ser usada para especificar o conjunto de caracteres MIME padrão para usar palavras codificadas e partes de texto que não especificam um conjunto de caracteres. Normalmente, o conjunto de caracteres MIME padrão é derivado do conjunto de caracteres Java padrão, conforme especificado na propriedade de sistema file.encoding. A maioria dos aplicativos não terá necessidade de definir explicitamente o conjunto de caracteres MIME padrão. Nos casos em que o conjunto de caracteres MIME padrão a ser usado para mensagens de email é diferente do conjunto de caracteres usado para arquivos armazenados no sistema, essa propriedade deve ser definida. 

Como você pode ler acima, por padrão, não há valor para o mail.mime.charset e a codificação do arquivo (propriedade file.encoding) é usada.

Para um email específico

No entanto, se você quiser especificar uma codificação específica para um e-mail específico, provavelmente deve usar os dois métodos setSubject(subject,charset) e setText(text,charset).

Se isso não funcionar, provavelmente sua entrada já está corrompida antes de chegar a este ponto. Em outras palavras, você provavelmente usou a codificação incorreta para coletar seus dados.

Tipos Mime são complicados

A setContent(content, "UTF-8") (como outras fontes afirmam) simplesmente não funcionará. Basta olhar para a assinatura deste método: setContent(Object content, String mimetype). Tipo Mime e charset são 2 coisas totalmente diferentes. Eu realmente deveria estar usando um dos métodos setText(...) com um parâmetro charset. 

Mas se você persistir em usar um tipo MIME para definir o conjunto de caracteres setContent(content,mimetype), use o formato correto. (não apenas "UTF-8", mas algo como "text/plain; charset=UTF-8"). Mas mais importante, esteja ciente de que todo tipo MIME tem sua própria maneira de lidar com charset.

  • Conforme especificado em RFC-2046 o conjunto de caracteres padrão para text/plain é US-ASCII, mas pode ser anulado com um parâmetro adicional charset. 
  • No entanto, em RFC-6657 deixa claro que o tipo text/xml determina o charset usando o conteúdo da mensagem. O parâmetro charset será apenas ignorado aqui.
  • E em RFC-2854 é declarado que text/html deve realmente sempre especificar um charset. Mas se você não fizer isso, ele usará ISO-8859-1 (= Latin-1).
66
bvdb

Talvez você deve fornecer também UTF-8 aqui

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

Você tem que olhar para http://www.coderanch.com/t/274480/Java/java/JavaMail-set-content-utf

29
Arsen Alexanyan

Depois de passar muito tempo na depuração, e procurando na internet por uma pista, eu encontrei uma solução para o meu problema.

Parece que sempre que eu enviava dados por meio de uma solicitação da web, meu aplicativo não codificava os caracteres com codificação UTF-8. Isso significava que os dados que eram enviados do meu formulário de contato, que continham æ, ø e å caracteres, não podiam ser manipulados corretamente pela codificação de caracteres.

A solução parecia configurar um Character Encoding Filter , no meu Deployment Descriptor, que codificava todos os pedidos de entrada da web para estarem com o caractere de codificação 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, "/*");
}

Esse filtro define a codificação como sendo UTF-8 e força a codificação para todas as solicitações que chegam na url '/ *'.

6
Rohwedder

É fácil, Executar seu projeto com o parâmetro -Dfile.ecoding = UTF-8! Ex: Java -Dfile.encoding = UTF-8 -jar MyProject.jar

0
user2582242