Как установить MimeBodyPart ContentType в «text / html»? - PullRequest
32 голосов
/ 17 февраля 2011

В программе ниже показано непредвиденное возвращаемое значение для многочастного типа MIME в HTML.Почему эта программа печатает «text / plain», а не «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());
  }
}

Я пробовал множество альтернативных способов, включая установку ByteArrayDataSource, обернутого в DataHandler, но безрезультатно.То же самое происходит, когда я пытаюсь сделать это с MimeMessage вместо MimeBodyPart.

Для компиляции и запуска в Linux:

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

Ответы [ 7 ]

49 голосов
/ 17 февраля 2011

Вызовите MimeMessage.saveChanges() во вложенном сообщении, которое обновит заголовки путем каскадного преобразования структуры MIME в вызов MimeBodyPart.updateHeaders() в вашей части тела.Именно этот вызов updateHeaders передает тип содержимого из DataHandler в заголовок MIME Content-Type детали.

Когда вы устанавливаете содержимое MimeBodyPart, JavaMail внутренне (и не очевидно) создаетобъект DataHandler, охватывающий переданный вами объект. Заголовок Content-Type детали не обновляется немедленно.

Нет простого способа сделать это в вашей тестовой программе, так как вы нене содержит MimeMessage и MimeBodyPart.updateHeaders() не public.


Вот рабочий пример, который освещает ожидаемые и неожиданные результаты:

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() );
  }
}
23 голосов
/ 17 февраля 2011

Не знаю почему (метод не задокументирован), но, посмотрев на исходный код, эта строка должна сделать это:

mime_body_part.setHeader("Content-Type", "text/html");
6 голосов
/ 14 декабря 2012

Попробуйте с этим:

msg.setContent(email.getBody(), "text/html; charset=ISO-8859-1");
4 голосов
/ 17 февраля 2011

Как насчет использования:

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

В документации getContentType говорится, что возвращаемое значение найдено с использованием getHeader (name).Так что, если вы установите заголовок с помощью setHeader, я думаю, все должно быть в порядке.

3 голосов
/ 13 января 2014

Существует метод setText(), который принимает 3 аргумента:

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

Параметры:

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

ПРИМЕЧАНИЕ. Подтип принимает текст после / в типах MIME, поэтомунапример,

  • text / html будет html
  • text / css будет css
  • и т. д.
1 голос
/ 13 января 2016

Используя "<h1>STRING<h1>".getBytes();, вы можете создать ByteArrayDataSource с типом контента и установить setDataHandler в своей MimeBodyPart

try:

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 голос
/ 09 апреля 2013

Для меня я установил два раза:

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

и он работал нормально.

...