第四講:使用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 ="[email protected]";
String to = "[email protected] , [email protected]";
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 ="[email protected]";
String to = "[email protected] ,[email protected]";
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)