第四讲:使用Transport类发送邮件(2)
三、发送邮件实例
3.2应用Authenticator类的编程实例
使用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方法关闭与邮件服务器的连接。
通过使用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);
}
}
3.3 使用代理服务器发送邮件
Java虚拟机本身提供对网络代理方面的支持,只要配置了socksProxyHost这个Java虚拟机系统属性,这个虚拟机发出的所有Socket网络连接就不在直接连接到目标计算机,而是连接到socksProxyHost属性指定的代理服务器的默认代理端口1080。也就是说一个Java网络应用程序的代码不需要进行任何修改,只要在启动Java虚拟机时设置socksProxyHost系统属性,这个Java网络应用程序就会使用socksProxyHost系统属性指定代理服务器进行连接和通信。而不是直接与邮件服务器进行通信。
设置属性有:
下面的配置要与电脑中的 代理服务器配置参数相同
java -DsocksProxyHost=代理服务器的IP地址 -DsocksProxyPort=808 MainSender
或者使用System.setProperty("socksProxyHost", IP); System.setProperty("socksProxyPort",port)
设置属性有:
下面的配置要与电脑中的 代理服务器配置参数相同
java -DsocksProxyHost=代理服务器的IP地址 -DsocksProxyPort=808 MainSender
或者使用System.setProperty("socksProxyHost", IP); System.setProperty("socksProxyPort",port)