2011-02-17 10 views
28

El siguiente programa muestra un valor de retorno inesperado para el tipo de mime multiparte HTML. ¿Por qué este programa imprime "text/plain" y no "text/html"?Cómo configurar MimeBodyPart ContentType en "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()); 
    } 
} 

me han tratado numerosas formas alternativas que incluyen el establecimiento de un ByteArrayDataSource envuelto en una DataHandler, pero fue en vano. Lo mismo sucede cuando pruebo esto con un MimeMessage en lugar de un MimeBodyPart.

Para compilar y ejecutar en Linux:

javac -classpath .:activation.jar:mail.jar Main.java 
java -classpath .:activation.jar:mail.jar Main 

Respuesta

39

Llame al MimeMessage.saveChanges() en el mensaje adjunto, que actualizará los encabezados mediante la cascada de la estructura MIME en una llamada al MimeBodyPart.updateHeaders() en su parte del cuerpo. Es esta llamada updateHeaders que transfiere el tipo de contenido del DataHandler al encabezado MIME Content-Type de la pieza.

Cuando se establece el contenido de un MimeBodyPart, JavaMail internamente (y obviamente no) crea un objeto DataHandler envolver el objeto que se ha pasado. Content-Type cabecera de la parte es no actualizado inmediatamente.

No hay una manera directa de hacerlo en su programa de prueba, ya que no tiene un contenedor que contiene MimeMessage y MimeBodyPart.updateHeaders() no es public.


Aquí está un ejemplo de trabajo que ilumina resultados esperados e inesperados:

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()); 
    } 
} 
+1

actualización: esto funcionó bien para mi programa de prueba pero en mi código real no fue así. la diferencia era que el código real era obtener un objeto MimeMessage creado por el sistema de correo, luego actualizar una parte y luego llamar a MimeMessage.saveChanges(). esto todavía no cambiaba el tipo mimet (aunque el contenido se cambió incluso antes de llamar a .saveChanges()). SOLUCIÓN: Creé un nuevo objeto MimeMessage (old_mime_message) del anterior, cambié el contenido y escribí el código, luego llamé .saveChanges() y funcionó bien para mí. – necromancer

+1

MimeMessage.saveChanges() era la magia que necesitaba para pasar nuestras pruebas junit. –

21

No sé por qué (el método no está documentada), pero mirando el código fuente, esta línea debe hacerlo:

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

gracias, estoy agradecido por su ayuda. Elegí una respuesta diferente anteriormente, ya que se ajusta mejor a la forma en que las bibliotecas están destinadas a ser utilizadas. pero su respuesta fue valiosa para mí al hacer un progreso inmediato para realizar una tarea urgente. gracias de nuevo. – necromancer

4

Qué acerca del uso:

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

En el documentation of getContentType se dice que el valor devuelto se encuentra u cantar getHeader (nombre). Entonces, si configuras el encabezado usando setHeader, creo que todo debería estar bien.

+1

gracias, estoy agradecido por su ayuda. Elegí una respuesta diferente anteriormente, ya que se ajusta mejor a la forma en que las bibliotecas están destinadas a ser utilizadas. pero su respuesta fue valiosa para mí al hacer un progreso inmediato para realizar una tarea urgente. gracias de nuevo. – necromancer

6

Pruebe con esto:

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

Para mí, puse dos veces:

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

y ha estado funcionando bien.

3

hay un método setText() que tiene 3 argumentos:

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

Parámetros:

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

nota: la toma subtipo texto después de/en los tipos MIME así por ej.

  • text/html html sería
  • text/css css sería
  • y así sucesivamente ..
+0

http://docs.oracle.com/javaee/6/api/javax/mail/internet/MimeMessage.html#setText(java.lang.String, java.lang.String, java.lang.String) –

1

Usando "<h1>STRING<h1>".getBytes(); puede crear un ByteArrayDataSource con el tipo de contenido y establecer setDataHandler en su MimeBodyPart

prueba:

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); 
Cuestiones relacionadas