web-dev-qa-db-fra.com

Comment définir le type de contenu MimeBodyPart sur "text / html"?

Le programme ci-dessous montre une valeur de retour inattendue pour le type mime multipartie HTML. Pourquoi ce programme imprime-t-il "text/plain" et non "text/html"?

public class Main {
  public static void main(String[] args) throws javax.mail.MessagingException, Java.io.IOException {
    javax.mail.internet.MimeBodyPart mime_body_part = new javax.mail.internet.MimeBodyPart();
    mime_body_part.setContent("<h1>foo</h1>", "text/html");
    System.out.println(mime_body_part.getContentType());
  }
}

J'ai essayé de nombreuses façons alternatives, y compris la définition d'un ByteArrayDataSource enveloppé dans un DataHandler, mais en vain. La même chose se produit lorsque j'essaie ceci avec un MimeMessage au lieu d'un MimeBodyPart.

Pour compiler et exécuter sous Linux:

javac -classpath .:activation.jar:mail.jar Main.Java
java -classpath .:activation.jar:mail.jar Main
32
necromancer

Appelez MimeMessage.saveChanges() sur le message joint, ce qui mettra à jour les en-têtes en cascadant la structure MIME en un appel à MimeBodyPart.updateHeaders() sur votre partie du corps. C'est cet appel updateHeaders qui transfère le type de contenu de DataHandler vers l'en-tête MIME Content-Type De la pièce.

Lorsque vous définissez le contenu d'un MimeBodyPart, JavaMail en interne (et non évidemment) crée un objet DataHandler enveloppant l'objet que vous avez transmis. L'en-tête Content-Type De la pièce est pas mis à jour immédiatement.

Il n'y a pas de moyen simple de le faire dans votre programme de test, car vous n'avez pas de contenant MimeMessage et MimeBodyPart.updateHeaders() n'est pas public.


Voici un exemple de travail qui éclaire les sorties attendues et inattendues:

public class MailTest {

  public static void main( String[] args ) throws Exception {
    Session mailSession = Session.getInstance( new Properties() );
    Transport transport = mailSession.getTransport();

    String text = "Hello, World";
    String html = "<h1>" + text + "</h1>";

    MimeMessage message = new MimeMessage( mailSession );
    Multipart multipart = new MimeMultipart( "alternative" );

    MimeBodyPart textPart = new MimeBodyPart();
    textPart.setText( text, "utf-8" );

    MimeBodyPart htmlPart = new MimeBodyPart();
    htmlPart.setContent( html, "text/html; charset=utf-8" );

    multipart.addBodyPart( textPart );
    multipart.addBodyPart( htmlPart );
    message.setContent( multipart );

    // Unexpected output.
    System.out.println( "HTML = text/html : " + htmlPart.isMimeType( "text/html" ) );
    System.out.println( "HTML Content Type: " + htmlPart.getContentType() );

    // Required magic (violates principle of least astonishment).
    message.saveChanges();

    // Output now correct.    
    System.out.println( "TEXT = text/plain: " + textPart.isMimeType( "text/plain" ) );
    System.out.println( "HTML = text/html : " + htmlPart.isMimeType( "text/html" ) );
    System.out.println( "HTML Content Type: " + htmlPart.getContentType() );
    System.out.println( "HTML Data Handler: " + htmlPart.getDataHandler().getContentType() );
  }
}
50
dkarp

Je ne sais pas pourquoi (la méthode n'est pas documentée), mais en regardant le code source, cette ligne devrait le faire:

mime_body_part.setHeader("Content-Type", "text/html");
23
JB Nizet

Essayez avec ceci:

msg.setContent(email.getBody(), "text/html; charset=ISO-8859-1");
6
mesrar

Qu'en est-il de l'utilisation:

mime_body_part.setHeader("Content-Type", "text/html");

Dans le documentation de getContentType il est dit que la valeur retournée est trouvée en utilisant getHeader (nom). Donc, si vous définissez l'en-tête à l'aide de setHeader, je suppose que tout devrait bien se passer.

4
foens

Il existe une méthode setText() qui prend 3 arguments:

public void setText(String text, String charset, String subtype)
    throws MessagingException

Paramètres:

text - the text content to set
charset - the charset to use for the text
subtype - the MIME subtype to use (e.g., "html")

REMARQUE: le sous-type prend du texte après/dans les types MIME, par exemple

  • text/html serait html
  • text/css serait css
  • etc..
3
Ravi Naik

Pour moi, j'ai réglé deux fois:

(MimeBodyPart)messageBodyPart.setContent(content, text/html)
(Multipart)multipart.addBodyPart(messageBodyPart)
(MimeMessage)msg.setContent(multipart, text/html)

et ça fonctionne bien.

1
lwpro2

En utilisant "<h1>STRING<h1>".getBytes(); vous pouvez créer un ByteArrayDataSource avec le type de contenu et définir setDataHandler dans votre MimeBodyPart

essayer:

String html "Test JavaMail API example. <br><br> Regards, <br>Ivonei Jr"
byte[] bytes = html.getBytes(); 
DataSource dataSourceHtml= new ByteArrayDataSource(bytes, "text/html");
MimeBodyPart bodyPart = new MimeBodyPart();
bodyPart.setDataHandler(new DataHandler(dataSourceHtml));

MimeMultipart mimeMultipart = new MimeMultipart();
mimeMultipart.addBodyPart(bodyPart);
1
ivoneijr