MimeMessage.saveChanges真的很慢

Baz*_*Baz 1 java junit jakarta-mail mime-message

由于包含了以下测试,因此执行大约需要5秒钟m.saveChanges().

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");
}
Run Code Online (Sandbox Code Playgroud)

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

Session s = mock(Session.class);
when(s.getProperties()).thenReturn(new Properties());
Run Code Online (Sandbox Code Playgroud)

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

jme*_*ens 6

修复人们在代码中首次使用JavaMail时最常犯的错误.

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

您最好使用会话属性来避免某些查找.

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

由于您没有传输邮件,因此请将代码更改为以下规则来应用规则#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");
}
Run Code Online (Sandbox Code Playgroud)

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