JAVA MAIL是利用現有的郵件賬戶發送郵件的工具,比如說,我在網易注冊一個郵箱賬戶,通過JAVA Mail的操控,我可以不親自登錄網易郵箱,讓程序自動的使用網易郵箱發送郵件。這一機制被廣泛的用在注冊激活和垃圾郵件的發送等方面。
Java郵件發送的大致過程是這樣的:
1、構建一個繼承自javax.mail.Authenticator的具體類,并重寫里面的getPasswordAuthentication()方法。此類是用作登錄校驗的,以確保你對該郵箱有發送郵件的權利。
2、構建一個properties文件,該文件中存放SMTP服務器地址等參數。
3、通過構建的properties文件和javax.mail.Authenticator具體類來創建一個javax.mail.Session。Session的創建,就相當于登錄郵箱一樣。剩下的自然就是新建郵件。
4、構建郵件內容,一般是javax.mail.internet.MimeMessage對象,并指定發送人,收信人,主題,內容等等。
5、使用javax.mail.Transport工具類發送郵件。
下面是我封裝的代碼,注釋也比較詳細。
1、首先是繼承自javax.mail.Authenticator的一個具體類。getPasswordAuthentication()方法也就是構建一個PasswordAuthentication對象并返回,有點費解JAVA Mail這樣的設計意圖,可能是javax.mail.Authenticator為我們提供了附加的保證安全的驗證措施吧。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
package com.mzule.simplemail; import javax.mail.Authenticator; import javax.mail.PasswordAuthentication; /** * 服務器郵箱登錄驗證 * * @author MZULE * */ public class MailAuthenticator extends Authenticator { /** * 用戶名(登錄郵箱) */ private String username; /** * 密碼 */ private String password; /** * 初始化郵箱和密碼 * * @param username 郵箱 * @param password 密碼 */ public MailAuthenticator(String username, String password) { this .username = username; this .password = password; } String getPassword() { return password; } @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password); } String getUsername() { return username; } public void setPassword(String password) { this .password = password; } public void setUsername(String username) { this .username = username; } } |
2、郵件發送類,剩下的步驟都是在這個類實現的。代碼中的SimpleMail是封裝了郵件主題和內容的一個POJO。覺得在一個方法參數中既包含主題又包含內容,不太合適,故重載了此方法。還有就是因為大多數郵箱的SMTP服務器地址都是可以通過郵箱地址算出來,簡單起見,提供了一個不需要SMTP服務器地址的構造器。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
package com.mzule.simplemail; import java.util.List; import java.util.Properties; import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMessage.RecipientType; /** * 簡單郵件發送器,可單發,群發。 * * @author MZULE * */ public class SimpleMailSender { /** * 發送郵件的props文件 */ private final transient Properties props = System.getProperties(); /** * 郵件服務器登錄驗證 */ private transient MailAuthenticator authenticator; /** * 郵箱session */ private transient Session session; /** * 初始化郵件發送器 * * @param smtpHostName * SMTP郵件服務器地址 * @param username * 發送郵件的用戶名(地址) * @param password * 發送郵件的密碼 */ public SimpleMailSender( final String smtpHostName, final String username, final String password) { init(username, password, smtpHostName); } /** * 初始化郵件發送器 * * @param username * 發送郵件的用戶名(地址),并以此解析SMTP服務器地址 * @param password * 發送郵件的密碼 */ public SimpleMailSender( final String username, final String password) { //通過郵箱地址解析出smtp服務器,對大多數郵箱都管用 final String smtpHostName = "smtp." + username.split( "@" )[ 1 ]; init(username, password, smtpHostName); } /** * 初始化 * * @param username * 發送郵件的用戶名(地址) * @param password * 密碼 * @param smtpHostName * SMTP主機地址 */ private void init(String username, String password, String smtpHostName) { // 初始化props props.put( "mail.smtp.auth" , "true" ); props.put( "mail.smtp.host" , smtpHostName); // 驗證 authenticator = new MailAuthenticator(username, password); // 創建session session = Session.getInstance(props, authenticator); } /** * 發送郵件 * * @param recipient * 收件人郵箱地址 * @param subject * 郵件主題 * @param content * 郵件內容 * @throws AddressException * @throws MessagingException */ public void send(String recipient, String subject, Object content) throws AddressException, MessagingException { // 創建mime類型郵件 final MimeMessage message = new MimeMessage(session); // 設置發信人 message.setFrom( new InternetAddress(authenticator.getUsername())); // 設置收件人 message.setRecipient(RecipientType.TO, new InternetAddress(recipient)); // 設置主題 message.setSubject(subject); // 設置郵件內容 message.setContent(content.toString(), "text/html;charset=utf-8" ); // 發送 Transport.send(message); } /** * 群發郵件 * * @param recipients * 收件人們 * @param subject * 主題 * @param content * 內容 * @throws AddressException * @throws MessagingException */ public void send(List<String> recipients, String subject, Object content) throws AddressException, MessagingException { // 創建mime類型郵件 final MimeMessage message = new MimeMessage(session); // 設置發信人 message.setFrom( new InternetAddress(authenticator.getUsername())); // 設置收件人們 final int num = recipients.size(); InternetAddress[] addresses = new InternetAddress[num]; for ( int i = 0 ; i < num; i++) { addresses[i] = new InternetAddress(recipients.get(i)); } message.setRecipients(RecipientType.TO, addresses); // 設置主題 message.setSubject(subject); // 設置郵件內容 message.setContent(content.toString(), "text/html;charset=utf-8" ); // 發送 Transport.send(message); } /** * 發送郵件 * * @param recipient * 收件人郵箱地址 * @param mail * 郵件對象 * @throws AddressException * @throws MessagingException */ public void send(String recipient, SimpleMail mail) throws AddressException, MessagingException { send(recipient, mail.getSubject(), mail.getContent()); } /** * 群發郵件 * * @param recipients * 收件人們 * @param mail * 郵件對象 * @throws AddressException * @throws MessagingException */ public void send(List<String> recipients, SimpleMail mail) throws AddressException, MessagingException { send(recipients, mail.getSubject(), mail.getContent()); } } |
3、調用上面的郵箱發送器,可以構建一個工廠類,工廠類可以封裝創建的過程,所以通過讀配置文件獲取郵箱用戶名,密碼都會變得十分方便。下面的代碼是我在寫觀察者模式的時候寫的,只是簡單演示了工廠類。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
package com.mzule.dp.observer.factory; import com.mzule.dp.observer.constant.MailSenderType; import com.mzule.simplemail.SimpleMailSender; /** * 發件箱工廠 * * @author MZULE * */ public class MailSenderFactory { /** * 服務郵箱 */ private static SimpleMailSender serviceSms = null ; /** * 獲取郵箱 * * @param type 郵箱類型 * @return 符合類型的郵箱 */ public static SimpleMailSender getSender(MailSenderType type) { if (type == MailSenderType.SERVICE) { if (serviceSms == null ) { "hidden" ); } return serviceSms; } return null ; } } |
4、發送郵件,還是觀察者模式DEMO里面的代碼,呼呼。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
package com.mzule.dp.observer.observer; import java.util.ArrayList; import java.util.List; import java.util.Observable; import java.util.Observer; import javax.mail.MessagingException; import javax.mail.internet.AddressException; import com.mzule.dp.observer.constant.MailSenderType; import com.mzule.dp.observer.factory.MailSenderFactory; import com.mzule.dp.observer.po.Product; import com.mzule.simplemail.SimpleMailSender; public class ProductPriceObserver implements Observer { @Override public void update(Observable obj, Object arg) { Product product = null ; if (obj instanceof Product) { product = (Product) obj; } if (arg instanceof Float) { Float price = (Float) arg; Float decrease = product.getPrice() - price; if (decrease > 0 ) { // 發送郵件 SimpleMailSender sms = MailSenderFactory .getSender(MailSenderType.SERVICE); List<String> recipients = new ArrayList<String>(); try { for (String recipient : recipients) { sms.send(recipient, "價格變動" , "您關注的物品" + product.getName() + "降價了,由" + product.getPrice() + "元降到" + price + "元,降幅達" + decrease + "元人民幣。趕快購物吧。" ); } } catch (AddressException e) { e.printStackTrace(); } catch (MessagingException e) { e.printStackTrace(); } } } } } |
5、查看郵件是否發送成功了。
以上就是java郵件發送的全部過程,希望對大家的學習有所幫助。