web-dev-qa-db-fra.com

utf 8 charset ne fonctionne pas avec javax mail

J'ai utilisé l'API Javax Mail pour l'envoi de courriers électroniques. J'utilise un formulaire de contact pour envoyer l'entrée, qui doit être envoyée à un courrier électronique spécifique.

L'e-mail est envoyé sans problème, bien que je sois danois et que j'ai donc besoin de trois caractères danois: "æ", "ø" et "å", dans le sujet et le texte de l'e-mail.

J'ai donc vu que je pouvais utiliser le codage de caractères UTF-8 pour fournir ces caractères, mais lorsque mon courrier est envoyé, je ne vois que des lettres étranges - "ã¦", "ã¸" et "ã ¥" - à la place du lettres danoises - "æ", "ø" et "å".

Ma méthode pour envoyer l'e-mail ressemble à ceci

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

S'il vous plaît, aidez-moi à découvrir comment je peux corriger cette "erreur".

41
Rohwedder

Pour tous les e-mails

Il existe quelques propriétés système liées au mailing , qui peuvent probablement simplifier votre code. Je parle en fait de cette propriété spécifique: "mail.mime.charset".

La propriété mail.mime.charset System peut être utilisée pour spécifier le jeu de caractères MIME par défaut} à utiliser pour les mots codés et les parties de texte qui ne spécifient pas autrement de jeu de caractères. Normalement, le jeu de caractères MIME par défaut est dérivé du jeu de caractères Java par défaut, comme spécifié dans la propriété Système file.encoding. La plupart des applications n'auront pas besoin de définir explicitement le jeu de caractères MIME par défaut. Dans les cas où le jeu de caractères MIME à utiliser pour les messages électroniques est différent de celui utilisé pour les fichiers stockés sur le système, cette propriété doit être définie. 

Comme vous pouvez le lire ci-dessus, par défaut, il n'y a pas de valeur pour mail.mime.charset et le codage de fichier (propriété file.encoding) est utilisé.

Pour un e-mail spécifique

Toutefois, si vous souhaitez spécifier un codage spécifique pour un courrier électronique spécifique, vous devez probablement utiliser les méthodes à 2 paramètres setSubject(subject,charset) et setText(text,charset).

_ {Si cela ne fonctionne pas, votre entrée est probablement déjà corrompue avant d'atteindre ce point. En d'autres termes, vous avez probablement utilisé le mauvais codage pour collecter vos données}.

Les types de mime sont compliqués

setContent(content, "UTF-8") (comme le prétendent d'autres sources) ne fonctionnera tout simplement pas. Il suffit de regarder la signature de cette méthode: setContent(Object content, String mimetype). Le type et le jeu de caractères Mime sont deux choses totalement différentes. Mon dieu, vous devriez vraiment utiliser l'une des méthodes setText(...) avec un paramètre charset. 

Mais si vous persistez à utiliser un type MIME pour définir le jeu de caractères setContent(content,mimetype), utilisez le format correct. (pas seulement "UTF-8", mais quelque chose comme "text/plain; charset=UTF-8"). Mais plus important encore, sachez que chaque type mime a sa propre façon de gérer les jeux de caractères.

  • Comme spécifié dans RFC-2046 , le jeu de caractères par défaut pour text/plain est US-ASCII, mais peut être remplacé par un paramètre de jeu de caractères supplémentaire. 
  • Cependant, dans RFC-6657 indique que le type text/xml détermine le jeu de caractères en utilisant le contenu du message. _ {Le paramètre charset sera simplement ignoré ici.} _
  • Et dans RFC-2854 , il est indiqué que text/html devrait vraiment toujours spécifier un jeu de caractères. Mais si vous ne le faites pas, il utilisera alors ISO-8859-1 (= Latin-1).
66
bvdb

Peut-être devriez-vous aussi fournir UTF-8 ici

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

Vous devez regarder http://www.coderanch.com/t/274480/Java/java/JavaMail-set-content-utf

29
Arsen Alexanyan

Après avoir passé beaucoup de temps à déboguer et à chercher un indice sur Internet, j'ai trouvé une solution à mon problème.

Il semble que chaque fois que j'envoyais des données via une requête Web, mon application ne codait pas les caractères avec le codage UTF-8. Cela signifiait que les données envoyées à partir de mon formulaire de contact, contenant des caractères æ, ø et å, ne pouvaient pas être traitées correctement par le codage des caractères.

La solution semblait mettre en place un Character Encoding Filter , dans mon descripteur de déploiement, qui encoderait toutes les demandes entrantes provenant du Web afin de les encoder avec le codage 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, "/*");
}

Ce filtre définit le codage sur UTF-8 et force le codage à toutes les demandes provenant de l'URL '/ *'.

6
Rohwedder

C'est facile, lancez votre projet avec le paramètre -Dfile.encoding = UTF8! Ex: Java -Dfile.encoding = UTF-8 -jar MyProject.jar

0
user2582242