我有一个返回会话的方法。我的目标是在调用该方法时它总是应该返回一个新会话。我有一个网络应用程序,当我单击“开始”或“发送”时,它总是连接并发送邮件。
我有以下情况:
- 我 connect() 到需要我自己的自定义信任库的服务器。
- 如果我连接到这个服务器,我应该从下拉框中选择 truststorename.jks。它应该工作。如果我没有选择我的信任库,那么应该抛出一个异常。
- 如果我连接到另一个不需要我自己的自定义信任库的服务器,那么我可以选择“无”。所以java采用默认配置。
应该抛出的异常是 javamail 的 Transport.connect() 方法:
java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
问题:
现在,当我启动或重新启动 Web 应用程序时 - 它只在第一次工作。
因此,如果我选择自己的信任库,它毫无例外地工作。但是后来我从下拉框中选择“无”或“无”,但它仍然成功发送而不是抛出异常。所以我认为旧会话仍然存在,只有在我重新部署网络应用程序时才会创建一个新会话。也许与系统属性有冲突?还是码头?
private Session connect(SMTPTask task) {
log.debug("Connecting to SMTP");
Properties props = new Properties();
Properties systemProps = System.getProperties();
if (task.getKeyStorePath().contains("None")) {
systemProps.remove("javax.net.ssl.trustStore");
systemProps.remove("javax.net.ssl.trustStorePassword");
System.setProperties(systemProps);
props.remove("mail.smtp.ssl.socketFactory");
} else {
systemProps.put("javax.net.ssl.trustStore", "src/main/resources/stores/" + task.getKeyStorePath());
systemProps.put("javax.net.ssl.trustStorePassword", "changeit");
System.setProperties(systemProps);
SSLSocketFactory factory = null;
try {
SSLContext ctx;
KeyManagerFactory kmf;
KeyStore ks;
char[] passphrase = "changeit".toCharArray();
ctx = SSLContext.getInstance("TLS");
kmf = KeyManagerFactory.getInstance("SunX509");
ks = KeyStore.getInstance("JKS");
URL resource = this.getClass().getResource("/stores/" + task.getKeyStorePath());
File file = new File(resource.toURI());
FileInputStream fis = new FileInputStream(file);
ks.load(fis, passphrase);
fis.close();
kmf.init(ks, passphrase);
ctx.init(kmf.getKeyManagers(), null, null);
factory = ctx.getSocketFactory();
props.put("mail.smtp.ssl.socketFactory", factory);
} catch (Exception e) {
log.error("Error with SSLFactory", e);
}
}
String host = task.getHost();
String port = String.valueOf(task.getPort());
props.put("mail.smtps.host", host);
props.put("mail.smtps.port", port);
props.put("mail.smtps.auth", "true");
props.put("mail.imaps.fetchsize", "22020096");
return Session.geInstance(props);
}
我在其他地方做:
public void send() {
...
Session s = connect(task);
...
}
编辑:
我不想用 MailSSLFactory 来做:
private Session connect(SMTPTask task) {
...
try {
MailSSLSocketFactory factory = new MailSSLSocketFactory();
KeyManagerFactory kmf= KeyManagerFactory.getInstance("SunX509");
KeyStore ks = KeyStore.getInstance("JKS");
char[] passphrase = "changeit".toCharArray();
URL resource = this.getClass().getResource("/stores/" + task.getKeyStorePath());
File file = new File(resource.toURI());
FileInputStream fis = new FileInputStream(file);
ks.load(fis, passphrase);
fis.close();
kmf.init(ks,passphrase);
factory.setKeyManagers(kmf.getKeyManagers());
factory.setTrustAllHosts(true);
props.put("mail.smtp.ssl.socketFactory", factory);
} catch (Exception e) {
log.error("Error with SSLFactory", e);
}
}
props.put("mail.smtps.host", host);
props.put("mail.smtps.port", port);
props.put("mail.smtps.auth", "true");
props.put("mail.imaps.fetchsize", "22020096");
return Session.getInstance(props);
}