セッションを返すメソッドがあります。私の目標は、メソッドが呼び出されたときに常に新しいセッションを返すことです。Web アプリケーションがあり、[開始] または [送信] をクリックすると、常に接続してメールを送信します。
次のケースがあります。
- 独自のカスタム トラストストアが必要なサーバーに connect() します。
- このサーバーに接続する場合は、ドロップダウン ボックスから truststorename.jks を選択する必要があります。そして、それはうまくいくはずです。トラストストアを選択しないと、例外がスローされます。
- 独自のカスタム トラストストアを必要としない別のサーバーに接続する場合は、[なし] を選択できます。そのため、Java はデフォルトの構成を取ります。
スローされる例外は、javamail の Transport.connect() メソッドにあります。
java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
問題:
webapplication を起動または再起動すると、初めて機能します。
したがって、独自のトラストストアを選択すると、例外なく機能します。しかし、ドロップダウン ボックスから [Nothing] または [None] を選択しても、例外がスローされる代わりに正常に送信されます。したがって、古いセッションはまだそこにあり、Web アプリを再デプロイするときにのみ新しいセッションが作成されると思います。System-Properties と競合している可能性がありますか? それとも桟橋?
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);
}