MimeMessage.saveChanges真的很慢

时间:2017-06-08 12:11:24

标签: java junit javamail mime-message

由于包含m.saveChanges()

,以下测试大约需要5秒钟才能执行
import org.junit.Before;
import org.junit.Test;    
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;
import java.io.IOException;
import java.util.Properties;
import static org.junit.Assert.assertEquals;   
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

@Test
public void test1() throws MessagingException, IOException {
    Session s = Session.getDefaultInstance(new Properties());
    MimeMessage m = new MimeMessage(s);
    m.setContent("<b>Hello</b>", "text/html; charset=utf-8");
    m.saveChanges();
    assertEquals(m.getContent(), "<b>Hello</b>");
    assertEquals(m.getContentType(), "text/html; charset=utf-8");
}

我也用mockito嘲笑了Session,但它没有帮助:

Session s = mock(Session.class);
when(s.getProperties()).thenReturn(new Properties());

这是什么问题?我可以嘲笑什么来加快速度?

1 个答案:

答案 0 :(得分:5)

首先在代码中修复most common mistakes people make when using JavaMail

DNS lookup会影响某些机器的性能。对于JDK,您可以更改用于缓存DNS查找的安全性属性networkaddress.cache.ttl and networkaddress.cache.negative.ttl或设置系统属性sun.net.inetaddr.ttl and sun.net.inetaddr.negative.ttl。 JDK 7及更高版本中的默认行为可以很好地缓存。

最好,您可以使用会话属性来避免某些查找。

  1. 设置mail.smtp.localhost的会话属性,以防止在HELO命令上进行名称查找。
  2. 设置mail.from or mail.host的会话属性(不是协议版本),因为这会阻止InternetAddress.getLocalAddress(Session)上的名称查找。致电MimeMessage.saveChanges()MimeMessage.updateHeaders()MimeMessage.updateMessageID()MimeMessage.setFrom()会触发此方法。
  3. 设置mail.smtp.from的会话属性,以防止查找EHLO命令。
  4. 或者,如果您的代码依赖于mail.mime.address.usecanonicalhostname,则可以将系统属性setFrom()设置为false,但这应该由#2点处理。
  5. 对于IMAP,您可以尝试将mail.imap.sasl.usecanonicalhostname设置为false,这是默认值。
  6. 由于您没有传输邮件,请将代码更改为:

    以应用规则#2
    @Test
    public void test1() throws MessagingException, IOException {
        Properties props = new Properties();
        props.put("mail.host", "localhost"); //Or use IP.
        Session s = Session.getInstance(props);
        MimeMessage m = new MimeMessage(s);
        m.setContent("<b>Hello</b>", "text/html; charset=utf-8");
        m.saveChanges();
        assertEquals(m.getContent(), "<b>Hello</b>");
        assertEquals(m.getContentType(), "text/html; charset=utf-8");
    }
    

    如果要传输消息,请合并规则#1,#2和#3,这将阻止访问主机系统进行名称查找。如果要在传输过程中阻止所有DNS查找,则必须使用IP地址。