使用Authenticator类的情况:当直接使用Transport的无参方法connect或者是Transport的静态方法直接发送邮件时,若服务器需要认证信息者则这两个方法都不能提供,因此要在创建Session对象时提供了Authenticator的认证信息,则就可以直接使用了。
通过使用Authenticator类的方式向邮件服务器提供认证信息可以按照以下步骤和思路进行编写:
1. 编写抽象类Authenticator的实现子类,在子类中覆盖父类的getPasswordAuthentication方法,并返回封装用户名和密码的PasswordAuthentication对象;
2. 调用Session.getInstance(Properties, Authenticator)方法获得Session类的实例对象,并把Authenticator对象注册到Session对象中。
3. 使用Session对象创建代表邮件消息内容的Message对象
4. 调用Transport.send静态方法发送Message对象中的邮件消息内容。send方法将从Message对象中获得Session对象的引用,然后将调用Session对象中注册的Authenticator对象从中获取认证信息后传递给邮件服务器。或者首先使用Transport的无参connect方法连接邮件服务器然后使用sendMessage发送发送邮件;最后调用close方法关闭与邮件服务器的连接。
public class MyAuthentication extends Authenticator {
private String username;
private String password;
public MyAuthentication(String username, String password) {
this.username = username;
this.password = password;
}
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
}
public class TransportWithAuthentication {
public static void main(String[] args) throws Exception {
String smtpServer ="smtp.163.com";
String protocol = "smtp";
String username = "XXX";
String password = "XXX";
String from ="XXX@163.com";
String to = "XXX@gmail.com , XXX@qq.com";
String subject = "测试邮件";
String body = "authenticator 测试";
Properties props = new Properties();
props.setProperty("mail.transport.protocol", protocol);
props.setProperty("mail.host", smtpServer);
props.setProperty("mail.smtp.auth", "true");
MyAuthentication authentication = new MyAuthentication(username, password);
Session session = Session.getInstance(props, authentication);
session.setDebug(true);
//创建代表邮件的MimeMessage对象
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.setRecipients(RecipientType.TO, InternetAddress.parse(to));
message.setSentDate(new Date());
message.setSubject(subject);
message.setText(body);
//保存并且生成邮件对象
message.saveChanges();
//建立发送邮件的对象
Transport sender = session.getTransport();
Transport.send(message);
//或是使用下面的方法
/* sender.connect();
sender.sendMessage(message, message.getRecipients(RecipientType.TO));
sender.close();*/
}
}
实际上可以使用匿名类实现上面的程序,这种方式的思想就是设计模式中的策略模式(封装变化)。其代码如下:
public class Transport2 {
public static void main(String[] args) throws Exception {
String smtpServer ="smtp.163.com";
String protocol = "smtp";
final String username = "XXX";
final String password = "XXX";
String from ="XXX@163.com";
String to = "XXX@gmail.com ,XXX@qq.com";
String subject = "测试邮件";
String body = "authenticator 测试";
Properties props = new Properties();
props.setProperty("mail.transport.protocol", protocol);
props.setProperty("mail.host", smtpServer);
props.setProperty("mail.smtp.auth", "true");
Session session = Session.getInstance(props,
new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
//匿名只能访问函数内容的final类型的变量,可以访问外部类的成员变量
return new PasswordAuthentication(username, password);
}
}
);
session.setDebug(true);
//创建代表邮件的MimeMessage对象
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.setRecipients(RecipientType.TO, InternetAddress.parse(to));
message.setSentDate(new Date());
message.setSubject(subject);
message.setText(body);
//保存并且生成邮件对象
message.saveChanges();
//建立发送邮件的对象
Transport sender = session.getTransport();
Transport.send(message);
}
}