使用不同的兩個帳戶發送email時,第一個賬戶可以發送成功,但到第二個賬戶的時候就報出了501 mail from address must be same as authorization user的錯誤。
具體代碼如下:
import java.util.Date;
import java.util.List;
import java.util.Properties;
import javax.mail.Address;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
public class MailSend {
private String host = "smtp.qq.com";
/**
* 發送郵件
* @param receiver 接收人
* @param title 標題
* @param content 內容
* @throws Exception
*/
public void send(String receiver,String title,String content,String sendUser,String sendUserId,String sendPassword) throws Exception{
try
{
Properties props = new Properties(); // 獲取系統環境
Authenticator auth = new MailAutherticator(sendUserId,sendPassword); // 進行郵件服務器用戶認證
props.put("mail.smtp.host", host);
props.put("mail.smtp.auth", "true");
Session session = Session.getDefaultInstance(props, auth);
MimeMessage message = new MimeMessage(session);// 設置session,和郵件服務器進行通訊。
message.setSubject(title); // 設置郵件主題
message.setText(content); // 設置郵件正文
message.setSentDate(new Date()); // 設置郵件發送日期
Address address = new InternetAddress(sendUser);
message.setFrom(address); // 設置郵件發送者的地址
message.reply(false);
//處理多用戶發送
Address[] multipleAddress = null;
String[] receivers = receiver.split(",");
if(receivers.length>0){
multipleAddress = new Address[receivers.length];
for(int i=0;i<receivers.length;i++){
String tmpReceiver = receivers[i].trim();
Address toAddress = new InternetAddress(tmpReceiver);
multipleAddress[i] = address;
}
}
message.addRecipients(Message.RecipientType.TO, multipleAddress); //收件人
Transport.send(message); // 發送郵件
} catch (Exception ex){
ex.printStackTrace();
throw new Exception(ex.getMessage());
}
}
/**
* 測試郵件
* @param args
*/
public static void main(String[] args) {
MailSend sendMail = new MailSend();
try {
String receiver = "XXXXXX@qq.com" ;//多封郵件請用逗號隔開
String title = "主題-測試郵件";
String content = "郵件內容-測試郵件";
String sendUser = "XXXXXX@qq.com";
String sendPassword = "XXXXXX";
String SendUserId = "XXXXXX";
sendMail.send(receiver,title,content,sendUser,SendUserId,sendPassword);//發送郵件
System.out.println("發送成功!");
sendUser = "XXXXXXXX@qq.com";
sendPassword = "XXXXXXX";
SendUserId = "XXXXXXXX";
/*運行到此處時就會報錯,但前一個send不執行的話,此處就正常運行*/ sendMail.send(receiver,title,content,sendUser,SendUserId,sendPassword);//發送郵件
System.out.println("發送成功!");
} catch (Exception e) {
e.printStackTrace();
}
}
Session session = Session.getDefaultInstance(props, auth);
以上改成
Session session = Session.getInstance(props, auth);
就可以了
何謂getDefaultInstance?
從處理流程中可以看出,首先是從緩存中查找是否有properties存在
如果存在,則加載默認的properties
如果不存在才加載用戶自己定義的properties,
所以當一個應用為每個用戶獨立創建properties的時候,還是應該調用getInstance,
除非你希望有一個默認的properties讓用戶使用
問 題找到了,因為它會首先去內存和系統文件中去找properties,所以不管我在頁面改幾次數據,其實在后台中生成session時都和系統啟動時的一 樣,所以在MailUtil.sendTextMessage(mailSession,RptTaskMailConfig.Sender,
receiver,null,mail_subject,mail_content,"GB2312",null);時session里的sender和傳入的sender不一致,因此出錯,修改Session.getDefaultInstance(props, authentic);為Session.getInstance(props, authentic);后,可以正確發送修改帳號,密碼等資料后的郵件.OK
最后再補充一下,session.getdefaultinstance和getinstance的區別 :
如果想要同時使用兩個帳號發送javamail,比如使用1@a.com發送1#郵件,使用2@a.com發送2#郵件,這時候,你就需要同時創建兩個java.mail.Session對象。但是如果你仍然使用Session.getDefaultInstance創建session對象的話,你會發現,第二個username:2@a.com創建的session永遠都和第一個一樣,這是為什么呢?因為,getDefaultInstance是真正單例模式,而且,里面的username和password屬性是final型的,無法更改。所以,你會發現兩封email都是由1@a.com發出來的。所以這個時候你要使用javax.mail.Session.getInstance()方法來創建session對象。