Spring02-模擬用戶登錄,發(fā)送郵件
一.注解方式注入 bean
對(duì)于 bean 的注入,除了使用 xml 配置以外假勿,注解的配置簡(jiǎn)化開發(fā)的速度粒没,使程
序看上去更簡(jiǎn)潔曲管。對(duì)于注解的解釋,spring
對(duì)于注解有專門的解釋器镀琉,對(duì)定義的注解
進(jìn)行解析峦嗤,實(shí)現(xiàn)對(duì)應(yīng) bean 對(duì)象的注入,反射技術(shù)實(shí)現(xiàn)屋摔。
1.加入 spring-aop jar 包 spring-aop-4.3.2.RELEASE.jar
2.Xml 配置: 加入 context 命名空間 和 xsd 地址\
- 添加<context:annotation-config/> 配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 開啟注解注入配置 -->
<context:annotation-config/>
對(duì)于 bean 的注入常用注解類型
@Autowired 屬性字段或 set 方法上
@Resource 屬性字段上或 set 方法上
區(qū)別: @Autowired 默認(rèn)按 bean 的類型匹配 可以修改 按名稱匹配 和
@Qualifier 配合使用
@Resource 默認(rèn)按名稱進(jìn)行裝配烁设, 名稱可以通過 name 屬性進(jìn)行指定, 如果沒
有指定 name 屬性钓试, 當(dāng)注解寫在字段上時(shí)装黑, 默認(rèn)取字段名進(jìn)行匹配注入, 如果
注解寫在 setter 方法上默認(rèn)取屬性名進(jìn)行裝配弓熏。 當(dāng)找不到與名稱匹配的 bean
時(shí)才按照類型進(jìn)行裝配恋谭。 但是需要注意的是,如果 name 屬性一旦指定挽鞠,
就只會(huì)按照名稱進(jìn)行裝配疚颊。
推薦使用@Resource 注解是屬于 J2EE 的狈孔,減少了與 spring 的耦合。
二材义、 Spring Ioc 容器自動(dòng)掃描管理 bean
實(shí)際的開發(fā)中均抽,bean 的數(shù)量非常多,采用手動(dòng)配置 bean 的方式已無法滿足生
產(chǎn)需要其掂,spring 這時(shí)候同樣提供了掃描的方式油挥,對(duì)掃描到的 bean
對(duì)象統(tǒng)一進(jìn)行管理,
簡(jiǎn)化開發(fā)配置款熬,提高開發(fā)效率喘漏。
<context:component-scan base-package="com.shsxt"/>
**不需要再配置
<context:annotation-config/>
同時(shí)對(duì)于被 spring 管理的 bean 類的定義上需要加入對(duì)應(yīng)的注解定義
開發(fā)中建議(開發(fā)中的一種約定)
Dao 層:@Repository
Service 層:@Service
視圖控制層:@Controller
如果對(duì)于開發(fā)的類實(shí)在不明確到底屬于哪個(gè)層,可以使用@Component 注解定義华烟。
三翩迈、 借助 spring 模擬用戶登陸流程
1.配置pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.shsxt</groupId>
<artifactId>spring01</artifactId>
<version>1.0-SNAPSHOT</version>
<name>spring01</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
</dependencies>
<build>
</build>
</project>
2.配置spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 開啟包掃描 -->
<context:component-scan base-package="com.shsxt"/>
<!--<bean id="userController" class="com.shsxt.controller.UserController" lazy-init="true"></bean>-->
<bean id="userController" class="com.shsxt.controller.UserController" scope="prototype"></bean>
</beans>
3.Dao 層 根據(jù)用戶名查詢用戶記錄UserDao
@Repository
public class UserDao {
private final String NAME="zhangsan";
private final String PWD="123456";
public User queryUserByName(String name){
User user = null;
if(name.equals(NAME)){
user = new User();
user.setName(NAME);
user.setPwd(PWD);
}
return user;
}
}
4.新建po-->User類
public class User {
private String name;
private String pwd;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", pwd='" + pwd + '\'' +
'}';
}
}
5.Service 業(yè)務(wù)判斷處理UserService調(diào)用Dao層,進(jìn)行參數(shù)校驗(yàn)
@Service
public class UserService {
@Autowired
private UserDao userDao;
public ResultInfo login(String name, String pwd){
/**
* 1. 參數(shù)校驗(yàn)
* 2. 查詢用戶
* 3. 比較密碼是否正確
*/
ResultInfo info = new ResultInfo();
if(null==name || "".equals(name)){
info.setCode(300);
info.setMsg("用戶名為空");
return info;
}
if(null==pwd || "".equals(pwd)){
info.setCode(300);
info.setMsg("密碼為空");
return info;
}
User user = userDao.queryUserByName(name);
if(null==user){
info.setCode(300);
info.setMsg("用戶不存在");
return info;
}
if(pwd.equals(user.getPwd())){
info.setCode(200);
info.setMsg("登陸成功");
return info;
}else{
info.setCode(300);
info.setMsg("用戶名或密碼不正確");
return info;
}
}
}
6.定義業(yè)務(wù)處理返回消息模型新建model包ResultInfo存儲(chǔ)查詢信息
public class ResultInfo {
private Integer code;
private String msg;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
@Override
public String toString() {
return "ResultInfo{" +
"code=" + code +
", msg='" + msg + '\'' +
'}';
}
}
*7.controller層UserController調(diào)用service層加入登錄功能方法*
//@Lazy
//@Controller
public class UserController {
public UserController() {
System.out.println("UserController init...");
}
@Autowired
private UserService userService;
public ResultInfo login(String name, String pwd){
return userService.login(name, pwd);
}
}
8.Junit 通過 junit 進(jìn)行測(cè)試UserControllerTest測(cè)試類
public class UserControllerTest {
@Test
public void login() throws Exception {
ApplicationContext context =
new ClassPathXmlApplicationContext("spring.xml");
UserController userController = (UserController) context.getBean("userController");
ResultInfo info = userController.login("zhangsan", "123456");
System.out.println(info);
}
@Test
public void login02() throws Exception {
ApplicationContext context =
new ClassPathXmlApplicationContext("spring.xml");
System.out.println(context.isSingleton("userController"));
System.out.println(context.getBean("userController"));
System.out.println(context.getBean("userController"));
}
測(cè)試結(jié)果
四、 Bean 的作用域問題
默認(rèn)情況下盔夜,我們從 spring 容器中拿到的對(duì)象均是單例的负饲,對(duì)于 bean
的作用
域類型如下:
1、 singleton 作用域
注意: lazy-init 是懶加載, 如果等于 true 時(shí)作用是指 spring
容器啟動(dòng)的時(shí)候不
會(huì)去實(shí)例化這個(gè) bean, 而是在程序調(diào)用時(shí)才去實(shí)例化. 默認(rèn)是 false 即 spring
容器啟\動(dòng)時(shí)實(shí)例化.
默認(rèn)情況下喂链,被管理的 bean 只會(huì) IOC 容器中存在一個(gè)實(shí)例返十,對(duì)于所有獲取該
Bean 的操作 Spring 容器將只返回同一個(gè) Bean。
**容器在啟動(dòng)的情況下就實(shí)例化所有 singleton 的 bean 對(duì)象椭微,并緩存與容器中
單例的好處:
1)提前發(fā)現(xiàn)潛在的配置問題
2)Bean 對(duì)象存在于緩存中洞坑,使用時(shí)不用再去實(shí)例化 bean,加快程序運(yùn)行效率
**什么類型的對(duì)象適合作為單例對(duì)象來使用呢蝇率? service,dao,action 等
一般來說對(duì)于無狀態(tài)或狀態(tài)不可改變的
對(duì)象適合使用單例模式(什么是無狀態(tài)或狀態(tài)
不可改變)
實(shí)際上對(duì)象狀態(tài)的變化往往均是由于屬性值得變化而引起的迟杂,比如 user 類 年齡
屬性會(huì)有變化 屬性年齡的變化一般會(huì)引起 user
對(duì)象狀態(tài)的變化。對(duì)于我們的程序來
說本慕,無狀態(tài)對(duì)象 沒有實(shí)例變量的存在排拷,保證了線程的安全性,service
層業(yè)務(wù)對(duì)象即是
無狀態(tài)對(duì)象锅尘。線程安全的监氢。
2、 prototype 作用域
通過 scope=" prototype" 設(shè)置 bean 的類型 藤违,每次向 Spring 容器請(qǐng)求獲取
Bean 都返回一個(gè)全新的 Bean浪腐,相對(duì)于"singleton"來說就是不緩存
Bean,每次都是
一個(gè)根據(jù) Bean 定義創(chuàng)建的全新 Bean顿乒。
<bean id="userController" class="com.shsxt.controller.UserController" scope="prototype"></bean>
不是單例
3议街、 Web 應(yīng)用中的作用域(request、 session淆游、 globalsession)
request 作用域:表示每個(gè)請(qǐng)求需要容器創(chuàng)建一個(gè)全新 Bean傍睹。比如提交表單
的數(shù)據(jù)必須是對(duì)每次請(qǐng)求新建一個(gè) Bean
來保持這些表單數(shù)據(jù)隔盛,請(qǐng)求結(jié)束釋放這些數(shù)據(jù)。
session 作用域:表示每個(gè)會(huì)話需要容器創(chuàng)建一個(gè)全新
Bean拾稳。比如對(duì)于每個(gè)用
戶一般會(huì)有一個(gè)會(huì)話吮炕,該用戶的用戶信息需要存儲(chǔ)到會(huì)話中,此時(shí)可以將該 Bean
作用
域配置為 session 級(jí)別访得。
globalSession:類似于 session 作用域龙亲,其用于 portlet(Portlet 是基于
Java
的 Web 組件,由 Portlet 容器管理悍抑,并由容器處理請(qǐng)求鳄炉,生產(chǎn)動(dòng)態(tài)內(nèi)容)環(huán)境的
web 應(yīng)
用。如果在非 portlet 環(huán)境將視為 session 作用域搜骡。
配置方式和基本的作用域相同拂盯,只是必須要有 web 環(huán)境支持,并配置相應(yīng)的
容器監(jiān)聽器或攔截器從而能應(yīng)用這些作用域.
五记靡、 Bean 的生命周期
1.Bean 的定義
對(duì)比已經(jīng)學(xué)過的 servlet 生命周期(容器啟動(dòng)裝載并實(shí)例化 servlet
類谈竿,初始化
servlet,調(diào)用 service 方法摸吠,銷毀 servlet)空凸。
同樣對(duì)于 spring 容器管理的 bean 也存在生命周期的概念
**在 Spring 中,Bean 的生命周期包括 Bean 的定義寸痢、初始化呀洲、使用和銷毀 4
個(gè)階段
**在 Spring 中,通常是通過配置文檔的方式來定義 Bean
的啼止。在一個(gè)配置文檔中道逗,可以
定義多個(gè) Bean。
2族壳、 Bean 的初始化
Spring bean 初始化有兩種方式:
I.在配置文檔中通過指定 init-method 屬性來完成憔辫。
II.實(shí)現(xiàn) org.springframework.beans.factory.InitializingBean 接口。
Bean 對(duì)象實(shí)例化過程是在 spring 容器初始化 時(shí)被實(shí)例化的仿荆,但也不是不可改
變的,可以通過 lazy-init="true" 屬性延遲 bean
對(duì)象的初始化操作坏平,此時(shí)再調(diào)用
getbean 方法時(shí)才會(huì)進(jìn)行 bean 的初始化操作
<bean id="userServiceImpl"class="com.shsxt.service.impl.UserServiceImpl"
init-method="init" >
3.Bean 的使用
I.使用 BeanFactory
II.使用 ApplicationContext
4.Bean 的銷毀
實(shí)現(xiàn)銷毀方式(spring 容器會(huì)維護(hù) bean 對(duì)象的管理拢操,可以指定 bean 對(duì)象的銷
毀所要執(zhí)行的方法)\
<bean id="userServiceImpl"class="com.shsxt.service.impl.UserServiceImpl" init
method="init" destroy-method="destroy">
</bean>
通過 AbstractApplicationContext 對(duì)象,調(diào)用其 close 方法實(shí)現(xiàn) bean
的銷毀過程舶替。\
AbstractApplicationContext ctx=new ClassPathXmlApplicationContext("spring
application.xml");
ctx.close();
六令境、 JavaMail 概述
JavaMail 是由 Sun 定義的一套收發(fā)電子郵件的 API, 不同的廠商可以提供自
己的實(shí)現(xiàn)類顾瞪。 但它并沒有包含在 JDK 中舔庶, 而是作為 JavaEE 的一部分抛蚁。
廠商所提供的 JavaMail 服務(wù)程序可以有選擇地實(shí)現(xiàn)某些郵件協(xié)議, 常見的
郵件協(xié)議包括:
SMTP: 簡(jiǎn)單郵件傳輸協(xié)議惕橙, 用于發(fā)送電子郵件的傳輸協(xié)議瞧甩;
POP3: 用于接收電子郵件的標(biāo)準(zhǔn)協(xié)議;
IMAP: 互聯(lián)網(wǎng)消息協(xié)議弥鹦, 是 POP3 的替代協(xié)議肚逸。
這三種協(xié)議都有對(duì)應(yīng) SSL 加密傳輸?shù)膮f(xié)議, 分別是 SMTPS彬坏, POP3S 和 IMAPS朦促。
除 JavaMail 服務(wù)提供程序之外,JavaMail 還需要 JAF(JavaBeans Activation
Framework)來處理不是純文本的郵件內(nèi)容栓始, 這包括 MIME(多用途互聯(lián)網(wǎng)郵件擴(kuò)
展 ) 务冕、 URL 頁(yè) 面 和 文 件 附 件 等 內(nèi) 容 。 另 外 幻赚, JavaMail 依 賴
JAF(JavaBeans
Activation Framework)洒疚, JAF 在 Java6 之后已經(jīng)合并到 JDK 中, 而 JDK5
之前需
要另外下載 JAF 的類庫(kù)坯屿。
[6.1油湖、 協(xié)議介紹]{.smallcaps}
1、 介紹
在研究 JavaMail API 的細(xì)則之前领跛, 首先需要對(duì)于 API 用到的協(xié)議有個(gè)認(rèn)識(shí)乏德。
對(duì)于 java mail 來說用到的協(xié)議有一下 4 種:
SMTP
POP
IMAP
MIME
2、 SMTP
簡(jiǎn)單郵件傳輸協(xié)議(Simple Mail Transfer Protocol吠昭, SMTP) 由 RFC 821
定義喊括。
它定義了發(fā)送電子郵件的機(jī)制。 在 JavaMail API 環(huán)境中矢棚, 您基于 JavaMail
的程
序?qū)⒑湍墓净蛞蛱鼐W(wǎng)服務(wù)供應(yīng)商的(Internet Service Provider's郑什,
ISP's)
SMTP 服務(wù)器通信。 SMTP 服務(wù)器會(huì)中轉(zhuǎn)消息給接收方 SMTP 服務(wù)器以便最終讓
用戶經(jīng)由 POP 或 IMAP 獲得蒲肋。
3蘑拯、 POP
POP 代表郵局協(xié)議(Post Office Protocol) 。 目前用的是版本 3兜粘, 也稱
POP3申窘,
RFC 1939 定義了這個(gè)協(xié)議。 POP 是一種機(jī)制孔轴,
因特網(wǎng)上大多數(shù)人用它得到郵件剃法。
它規(guī)定每個(gè)用戶一個(gè)郵箱的支持。 這就是它所能做的路鹰,
而這也造成了許多混淆贷洲。
使用 POP3 時(shí)收厨, 用戶熟悉的許多性能并不是由 POP 協(xié)議支持的, 如查看有幾封
新郵件消息這一性能优构。 這些性能內(nèi)建于如 Eudora 或 Microsoft Outlook
之類的程
序中诵叁, 它們能記住一些事, 諸如最近一次收到的郵件俩块,
還能計(jì)算出有多少是新的黎休。
所以當(dāng)使用 JavaMail API 時(shí), 如果您想要這類信息玉凯, 您就必須自己算势腮。
4、 IMAP
IMAP 是更高級(jí)的用于接收消息的協(xié)議漫仆。 在 RFC 2060 中被定義捎拯, IMAP 代表
因特網(wǎng)消息訪問協(xié)議(Internet Message Access Protocol) , 目前用的是版本
4盲厌,
也稱 IMAP4署照。 在用到 IMAP 時(shí), 郵件服務(wù)器必需支持這個(gè)協(xié)議吗浩。 不能僅僅把使
用 POP 的程序用于 IMAP建芙, 并指望它支持 IMAP 所有性能。 假設(shè)郵件服務(wù)器支
持 IMAP懂扼, 基于 JavaMail 的程序可以利用這種情況 ---
用戶在服務(wù)器上有多個(gè)文
件夾(folder) 禁荸, 并且這些文件夾可以被多個(gè)用戶共享。
因?yàn)橛羞@一更高級(jí)的性能阀湿, 您也許會(huì)認(rèn)為所有用戶都會(huì)使用 IMAP赶熟。 事實(shí)并
不是這樣。 要求服務(wù)器接收新消息陷嘴, 在用戶請(qǐng)求時(shí)發(fā)送到用戶手中映砖,
還要在每個(gè)
用戶的多個(gè)文件夾中維護(hù)消息。 這樣雖然能將消息集中備份灾挨,
但隨著用戶長(zhǎng)期的
郵件夾越來越大邑退, 到磁盤空間耗盡時(shí), 每個(gè)用戶都會(huì)受到損失涨醋。 使用 POP瓜饥,
就能
卸載郵件服務(wù)器上保存的消息了。
5浴骂、 MIME
MIME 代表多用途因特網(wǎng)郵件擴(kuò)展標(biāo)準(zhǔn)(Multipurpose Internet Mail
Extensions) 。 它不是郵件傳輸協(xié)議宪潮。 但對(duì)傳輸內(nèi)容的消息溯警、
附件及其它的內(nèi)容
定義了格式趣苏。這里有很多不同的有效文檔: RFC 822、RFC 2045梯轻、RFC 2046 和
RFC
2047食磕。 作為一個(gè) JavaMail API 的用戶, 您通常不必對(duì)這些格式操心喳挑。
無論如何彬伦,
一定存在這些格式而且程序會(huì)用到它。
[6.3伊诵、 JavaMail 的關(guān)鍵對(duì)象]{.smallcaps}
JavaMail 對(duì)收發(fā)郵件進(jìn)行了高級(jí)的抽象单绑, 形成了一些關(guān)鍵的的接口和類,
它們構(gòu)成了程
序的基礎(chǔ)曹宴, 下面我們分別來了解一下這些最常見的對(duì)象搂橙。
Properties:屬性對(duì)象
由于 JavaMail 需要和郵件服務(wù)器進(jìn)行通信, 這就要求程序提供許多諸如服務(wù)
器地址笛坦、 端口区转、 用戶名、 密碼等信息版扩, JavaMail 通過 Properties
對(duì)象封裝這些屬
性西信息废离。 如下面的代碼封裝了兩個(gè)屬性信息:
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.sina.com.cn");
props.put("mail.smtp.auth", "true");
針對(duì)不同的的郵件協(xié)議, JavaMail 規(guī)定了服務(wù)提供者必須支持一系列屬性礁芦,
下表是針對(duì) SMTP 協(xié)議的一些常見屬性(屬性值都以 String 類型進(jìn)行設(shè)置蜻韭,
屬性
類型欄僅表示屬性是如何被解析的) :
其他幾個(gè)協(xié)議也有類似的一系列屬性, 如 POP3 的 mail.pop3.host宴偿、
mail.pop3.port 以及\IMAP 的 mail.imap.host湘捎、 mail.imap.port 等。
Session:會(huì)話對(duì)象
Session 是一個(gè)很容易被誤解的類窄刘, 這歸咎于混淆視聽的類名窥妇。
千萬不要以為這
里的 Session 像 HttpSession 一樣代表真實(shí)的交互會(huì)話, 但創(chuàng)建 Session
對(duì)象時(shí)娩践,
并沒有對(duì)應(yīng)的物理連接活翩, 它只不過是一對(duì)配置信息的集合。 Session
的主要作用
包括兩個(gè)方面:
1) 接收各種配置屬性信息: 通過 Properties 對(duì)象設(shè)置的屬性信息翻伺;
2) 初始化 JavaMail 環(huán)境: 根據(jù) JavaMail 的配置文件材泄, 初始化 JavaMail
環(huán)境,
以便通過 Session 對(duì)象創(chuàng)建其他重要類的實(shí)例吨岭。
Transport 和 Store:傳輸和存儲(chǔ)
郵 件 操 作 只 有 發(fā) 送 或 接 收 兩 種 處 理 方 式 拉宗, JavaMail 將 這 兩
種 不 同 操 作 描 述 為 傳 輸
(javax.mail.Transport) 和存儲(chǔ)(javax.mail.Store) ,
傳輸對(duì)應(yīng)郵件的發(fā)送, 而存儲(chǔ)對(duì)應(yīng)郵件
的接收旦事。
Message:消息對(duì)象
一旦獲得 Session 對(duì)象魁巩, 就可以繼續(xù)創(chuàng)建要發(fā)送的消息。 這由 Message
類來完成姐浮。 因
為 Message 是個(gè)抽象類谷遂, 您必需用一個(gè)子類, 多數(shù)情況下為
javax.mail.internet.MimeMessage卖鲤。
MimeMessage 是個(gè)能理解 MIME 類型和頭的電子郵件消息肾扰, 正如不同 RFC
中所定義的。 雖
然在某些頭部域非 ASCII 字符也能被譯碼蛋逾, 但 Message 頭只能被限制為用
US-ASCII 字符集晚。
Address:地址
一旦您創(chuàng)建了 Session 和 Message, 并將內(nèi)容填入消息后换怖, 就可以用 Address
確
定信件地址了甩恼。 和 Message 一樣, Address 也是個(gè)抽象類沉颂。 您用的
是 javax.mail.internet.InternetAddress 類条摸。
若創(chuàng)建的地址只包含電子郵件地址, 只要傳遞電子郵件地址到構(gòu)造器就行了铸屉。
Authenticator:認(rèn)證者
與 java 類一樣钉蒲, JavaMail API 也可以利用 Authenticator
通過用戶名和密碼訪
問受保護(hù)的資源。 對(duì)于 JavaMail API 來說彻坛, 這些資源就是郵件服務(wù)器顷啼。
JavaMail
Authenticator 在 javax.mail 包中, 而且它和 java.net 中同名的類
Authenticator 不
同昌屉。 兩者并不共享同一個(gè) Authenticator钙蒙, 因?yàn)?JavaMail API 用于 Java
1.1, 它沒
有 java.net 類別间驮。 要使用 Authenticator躬厌, 先創(chuàng)建一個(gè)抽象類的子類, 并
從 getPasswordAuthentication() 方法中返回 PasswordAuthentication 實(shí)例竞帽。
創(chuàng)建完
成后扛施, 您必需向 session 注冊(cè) Authenticator。 然后屹篓, 在需要認(rèn)證的時(shí)候疙渣,
就會(huì)通
知 Authenticator。 您可以彈出窗口堆巧,
也可以從配置文件中(雖然沒有加密是不安
全的) 讀取用戶名和密碼妄荔, 將它們作為 PasswordAuthentication
對(duì)象返回給調(diào)用
程序泼菌。
[6.4、 Java mail 發(fā)送郵件 環(huán)境準(zhǔn)備]{.smallcaps}
1.jar 下載
通過 java mail 發(fā)送郵件懦冰, 首先需要下載對(duì)應(yīng) Java mail jar 包 下載地址:
http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-eeplat-419426.html#javamail-1.4.5-oth-JPR
2.個(gè)人郵箱準(zhǔn)備這里以(163 郵箱為例)
注冊(cè) 163 郵箱灶轰, 登錄 163 郵箱后 設(shè)置郵箱賬戶開通 smtp 協(xié)議
登錄到郵箱后 獲取郵箱客戶端授權(quán)碼這里需要根據(jù)注冊(cè)時(shí)輸入的手機(jī)后輸入 163
服務(wù)器發(fā)送的驗(yàn)證碼來開通谣沸, 開通成功
記住個(gè)人授權(quán)訪問碼會(huì)以短信通知到對(duì)應(yīng)手機(jī)刷钢, 該授權(quán)碼是后面通過 Java mail
發(fā)送郵件的認(rèn)證密碼 非常重要 不要記錯(cuò).
6.5、 Java mail 郵件發(fā)送實(shí)現(xiàn)
1.發(fā)送普通文本郵件
1)pom.xml中加依賴
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.shsxt</groupId>
<artifactId>spring07-email</artifactId>
<version>1.0-SNAPSHOT</version>
<name>spring07-email</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- 添加JavaMail依賴 -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4</version>
</dependency>
<!-- spring 核心jar 依賴 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- spring 上下文環(huán)境 支持 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
</dependencies>
<build>
</build>
</project>
2)創(chuàng)建認(rèn)證類MyAtuhenticator繼承Authenticator
public class MyAuthenticator extends Authenticator {
private String username;
private String password;
public MyAuthenticator(String username, String password) {
this.username = username;
this.password = password;
}
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username,password);
}
}
3)創(chuàng)建發(fā)送類SendMail.java
public class SendMail {
public void send01() throws MessagingException {
//1.設(shè)置郵件服務(wù)器參數(shù)
//定義郵箱服務(wù)器配置
Properties props =new Properties();
//163郵件服務(wù)器地址
props.put("mail.smtp.host","smtp.163.com");
// 163 郵件服務(wù)器端口
props.put("mail.smtp.port", "25");
// 163 郵件服務(wù)器認(rèn)證屬性
props.put("mail.smtp.auth", "true");
//2創(chuàng)建session
Session session =Session.getInstance(props,
new MyAuthenticator("13255123823@163.com","why111"));
//3.定義消息
Message message =new MimeMessage(session);
//設(shè)置發(fā)件人和收件人
message.setFrom(new InternetAddress("13255123823@163.com"));
message.setRecipient(Message.RecipientType.TO,new InternetAddress("286763969@qq.com"));
message.setSentDate(new Date());//發(fā)送日期
message.setSubject("第一封郵件"); //發(fā)送主題
message.setText("hello, 歡迎你的回復(fù)!"); //發(fā)送內(nèi)容
//4.發(fā)送
Transport.send(message);
}
4)創(chuàng)建單元測(cè)試類SendMailTest類發(fā)送郵件
public class SendMailTest {
@Test
public void send01() throws MessagingException {
new SendMail().send01();
System.out.println("發(fā)送了一封郵件");
}
執(zhí)行測(cè)試 發(fā)送成功 后 進(jìn)入郵箱查看郵件 .
2.發(fā)送 html 郵件內(nèi)容和發(fā)送帶附件的內(nèi)容
1)sendMail類中添加新的方法
/**
* 發(fā)送html郵件
* @throws MessagingException
*/
public void send02() throws MessagingException {
//1.設(shè)置郵件服務(wù)器參數(shù)
//定義郵箱服務(wù)器配置
Properties props =new Properties();
//163郵件服務(wù)器地址
props.put("mail.smtp.host","smtp.163.com");
// 163 郵件服務(wù)器端口
props.put("mail.smtp.port", "25");
// 163 郵件服務(wù)器認(rèn)證屬性
props.put("mail.smtp.auth", "true");
//2創(chuàng)建session
Session session =Session.getInstance(props,
new MyAuthenticator("13255123823@163.com","why111"));
//3.定義消息
Message message =new MimeMessage(session);
//設(shè)置發(fā)件人和收件人
message.setFrom(new InternetAddress("13255123823@163.com"));
message.setRecipient(Message.RecipientType.TO,new InternetAddress("286763969@qq.com"));
message.setSentDate(new Date());//發(fā)送日期
message.setSubject("html郵件"); //發(fā)送主題
//html郵件
MimeMultipart multipart =new MimeMultipart();
MimeBodyPart bodyPart =new MimeBodyPart();
bodyPart.setContent(
"<html><body><a ,
"text/html;charset=utf-8");
multipart.addBodyPart(bodyPart);
message.setContent(multipart);
//4.發(fā)送
Transport.send(message);
}
/**
* 發(fā)送附件郵件
* @throws MessagingException
*/
public void send03() throws MessagingException, UnsupportedEncodingException {
//1.設(shè)置郵件服務(wù)器參數(shù)
//定義郵箱服務(wù)器配置
Properties props =new Properties();
//163郵件服務(wù)器地址
props.put("mail.smtp.host","smtp.163.com");
// 163 郵件服務(wù)器端口
props.put("mail.smtp.port", "25");
// 163 郵件服務(wù)器認(rèn)證屬性
props.put("mail.smtp.auth", "true");
//2創(chuàng)建session
Session session =Session.getInstance(props,
new MyAuthenticator("13255123823@163.com","why111"));
//3.定義消息
Message message =new MimeMessage(session);
//設(shè)置發(fā)件人和收件人
message.setFrom(new InternetAddress("13255123823@163.com"));
message.setRecipient(Message.RecipientType.TO,new InternetAddress("286763969@qq.com"));
message.setSentDate(new Date());//發(fā)送日期
message.setSubject("帶附件郵件"); //發(fā)送主題
//html郵件
MimeMultipart multipart =new MimeMultipart();
MimeBodyPart bodyPart =new MimeBodyPart();
bodyPart.setContent(
"<html><body><a ,
"text/html;charset=utf-8");
multipart.addBodyPart(bodyPart);
/*
防附件
*/
MimeBodyPart bodyPart02 =new MimeBodyPart();
FileDataSource fds =new FileDataSource(new File("E:\\課程資料\\G04-spring02-7.5.2019\\practice\\spring07email\\pom.xml"));
//設(shè)置附件
bodyPart02.setDataHandler(new DataHandler(fds));
//設(shè)置文件名
bodyPart02.setFileName(MimeUtility.encodeText("pom.xml"));
multipart.addBodyPart(bodyPart02);
//加入一張圖片
MimeBodyPart bodyPart3 =new MimeBodyPart();
FileDataSource fds2 =new FileDataSource(new File("C:\\Users\\Administrator\\Pictures\\11.jpg"));
//設(shè)置附件
bodyPart3.setDataHandler(new DataHandler(fds2));
//設(shè)置文件名
bodyPart3.setFileName(MimeUtility.encodeText("11.jpg"));
multipart.addBodyPart(bodyPart3);
message.setContent(multipart);
//4.發(fā)送
Transport.send(message);
}
}
2)SendMailTest類發(fā)送html郵件
public class SendMailTest {
@Test
public void send01() throws MessagingException {
new SendMail().send01();
System.out.println("發(fā)送了一封郵件");
}
@Test
public void send02() throws MessagingException {
new SendMail().send02();
System.out.println("發(fā)送了html郵件");
}
@Test
public void send03() throws Exception {
new SendMail().send03();
System.out.println("發(fā)送了附件郵件");
}
測(cè)試結(jié)果
3Java mail 郵件發(fā)送封裝\
1)郵件發(fā)送器方法封裝util包下建ShSxtMailSender
package com.shsxt.util;
import com.shsxt.MyAuthenticator;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.File;
import java.util.Date;
import java.util.List;
import java.util.Properties;
/**
* 簡(jiǎn)單封裝郵件發(fā)送器 發(fā)送郵件實(shí)現(xiàn)
* @author lp
*
*/
public class ShSxtMailSender {
public void sendHtmlMail(ShSxtMailSendInfo mailSendInfo){
Message message=null;
Session session=null;
try {
MyAuthenticator au=new MyAuthenticator(mailSendInfo.getUserName(), mailSendInfo.getUserPwd());
Properties props=new Properties();
// 163 郵件服務(wù)器地址
props.put("mail.smtp.host", mailSendInfo.getServerHost());
// 163 郵件服務(wù)器端口
props.put("mail.smtp.port",mailSendInfo.getServerPort());
// 163 郵件服務(wù)器認(rèn)證屬性
props.put("mail.smtp.auth", mailSendInfo.getFlag());
session=Session.getDefaultInstance(props, au);
message=new MimeMessage(session);
Address from=new InternetAddress(mailSendInfo.getFromAddress());
message.setFrom(from);
message.setSentDate(new Date());
if(null!=mailSendInfo.getToAddress()&&mailSendInfo.getToAddress().size()>0){
Address[] addresses=new Address[mailSendInfo.getToAddress().size()];
for(int i=0;i<mailSendInfo.getToAddress().size();i++){
Address address=new InternetAddress(mailSendInfo.getToAddress().get(i));
addresses[i]=address;
}
message.setRecipients(Message.RecipientType.TO, addresses);// 設(shè)置接收人地址
message.setSubject(mailSendInfo.getSubject());
Multipart multipart=new MimeMultipart();
BodyPart bodyPart=new MimeBodyPart();
bodyPart.setContent(mailSendInfo.getContent(), "text/html;charset=utf-8");
multipart.addBodyPart(bodyPart);
// 附件添加
List<String> files=mailSendInfo.getAttachFileNames();
if(null!=files&&files.size()>0){
for(int i=0;i<files.size();i++){
File tempFile=new File(files.get(i));
if(tempFile.exists()){
BodyPart temp=new MimeBodyPart();
temp.setDataHandler(new DataHandler(new FileDataSource(tempFile)));
temp.setFileName(MimeUtility.encodeText (tempFile.getName()));//設(shè)置文件名
multipart.addBodyPart(temp);//添加附件
}
}
}
// 設(shè)置郵件內(nèi)容
message.setContent(multipart);
Transport.send(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
2)郵件發(fā)送信息類簡(jiǎn)單封裝ShSxtMailSendInfo
package com.shsxt.util;
import java.util.List;
/**
* 郵件發(fā)送信息類
* 定義發(fā)送郵件時(shí) 郵件服務(wù)器 端口 發(fā)送方用戶名 密碼等字段
* @author lp
*
*/
public class ShSxtMailSendInfo {
private String serverHost;// 服務(wù)器主機(jī)
private String serverPort;//服務(wù)器端口
private String fromAddress;//發(fā)送方郵箱地址
private List<String> toAddress;// 接收方郵箱地址
private String userName;//郵件服務(wù)器用戶名
private String userPwd;//郵件服務(wù)器密碼
private String subject;//郵件主題
private String content;// 郵件內(nèi)容
private String flag="true";
private List<String> attachFileNames;//附件文件名
public String getFlag() {
return flag;
}
public void setFlag(String flag) {
this.flag = flag;
}
public String getServerHost() {
return serverHost;
}
public void setServerHost(String serverHost) {
this.serverHost = serverHost;
}
public String getServerPort() {
return serverPort;
}
public void setServerPort(String serverPort) {
this.serverPort = serverPort;
}
public String getFromAddress() {
return fromAddress;
}
public void setFromAddress(String fromAddress) {
this.fromAddress = fromAddress;
}
public List<String> getToAddress() {
return toAddress;
}
public void setToAddress(List<String> toAddress) {
this.toAddress = toAddress;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPwd() {
return userPwd;
}
public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public List<String> getAttachFileNames() {
return attachFileNames;
}
public void setAttachFileNames(List<String> attachFileNames) {
this.attachFileNames = attachFileNames;
}
}
3)測(cè)試SendMailTest類發(fā)送 html和附件郵件
/**
* 郵件發(fā)送封裝
*/
@Test
public void testMail01() {
ShSxtMailSendInfo shSxtMailSendInfo=new ShSxtMailSendInfo();
shSxtMailSendInfo.setServerHost("smtp.163.com");
shSxtMailSendInfo.setServerPort("25");
shSxtMailSendInfo.setUserName("shsxt_test01@163.com");
shSxtMailSendInfo.setUserPwd("shsxt123");
shSxtMailSendInfo.setSubject("shsxt全體郵件");
shSxtMailSendInfo.setFromAddress("shsxt_test01@163.com");
shSxtMailSendInfo.setContent("hello shsxt");
List<String> users=new ArrayList<String>();
users.add("shsxt_test01@163.com");
shSxtMailSendInfo.setToAddress(users);
ShSxtMailSender mailSender=new ShSxtMailSender();
mailSender.sendHtmlMail(shSxtMailSendInfo);
}
/**
* 封裝后發(fā)送帶附件郵件測(cè)試
*/
@Test
public void testMail02() {
ShSxtMailSendInfo shSxtMailSendInfo=new ShSxtMailSendInfo();
shSxtMailSendInfo.setServerHost("smtp.163.com");
shSxtMailSendInfo.setServerPort("25");
shSxtMailSendInfo.setUserName("shsxt_test01@163.com");
shSxtMailSendInfo.setUserPwd("shsxt123");
shSxtMailSendInfo.setSubject("shsxt全體郵件");
shSxtMailSendInfo.setFromAddress("shsxt_test01@163.com");
shSxtMailSendInfo.setContent("hello shsxt");
List<String> users=new ArrayList<String>();
users.add("shsxt_test01@163.com");
shSxtMailSendInfo.setToAddress(users);
// 添加附件
List<String> files=new ArrayList<String>();
files.add("E:\\java_28\\spring07mail\\28期.bmp");
files.add("E:\\java_28\\spring07mail\\pom.xml");
shSxtMailSendInfo.setAttachFileNames(files);
ShSxtMailSender mailSender=new ShSxtMailSender();
mailSender.sendHtmlMail(shSxtMailSendInfo);
}
七、 使用 Spring api 實(shí)現(xiàn)郵件發(fā)送
1.環(huán)境準(zhǔn)備
這里建立 maven 普通工程
添加坐標(biāo)依賴pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.shsxt</groupId>
<artifactId>spring07-mail</artifactId>
<version>1.0-SNAPSHOT</version>
<name>spring07-mail</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- 添加JavaMail依賴 -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4</version>
</dependency>
<!-- spring 核心jar 依賴 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- spring 上下文環(huán)境 支持 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
</dependencies>
<build>
</build>
</project>
2.配置文件配置郵件發(fā)送 bean
借助 spring 環(huán)境配置郵件發(fā)送相關(guān) bean,spring.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 開啟包掃描 -->
<context:component-scan base-package="com.shsxt"/>
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="smtp.163.com" />
<property name="port" value="25" />
<property name="defaultEncoding" value="utf-8"></property>
<property name="username" value="shsxt_test01@163.com"></property>
<property name="password" value="shsxt123"></property>
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.auth">true</prop>
</props>
</property>
</bean>
<bean id="templateMessage" class="org.springframework.mail.SimpleMailMessage">
<property name="from" value="shsxt_test01@163.com" />
<property name="subject" value="spring_mail" />
</bean>
<bean id="orderManager" class="com.shsxt.spring.SimpleOrderManager">
<property name="mailSender" ref="mailSender" />
<property name="templateMessage" ref="templateMessage" />
</bean>
<!-- 配置定時(shí)任務(wù) -->
<!-- 通過注解 -->
<!-- 開啟定時(shí)任務(wù)注解 -->
<task:annotation-driven />
<bean id="myJob02" class="com.shsxt.task.MyJob02"></bean>
</beans>
3.發(fā)送接口定義與實(shí)現(xiàn)
package-orderManger接口
/**
* 發(fā)送郵件接口定義
* @author lp
*
*/
public interface OrderManager {
void placeOrder();
}
package-SimpleorderManger實(shí)現(xiàn)類
**
* 接口實(shí)現(xiàn)類
*/
public class SimpleOrderManager implements OrderManager {
private MailSender mailSender;
private SimpleMailMessage templateMessage;
public void setMailSender(MailSender mailSender) {
this.mailSender = mailSender;
}
public void setTemplateMessage(SimpleMailMessage templateMessage) {
this.templateMessage = templateMessage;
}
@Override
public void placeOrder() {
SimpleMailMessage msg = new SimpleMailMessage(this.templateMessage);
msg.setTo("shsxt_test01@163.com");
msg.setText("test...asdasdasdsd");
try {
this.mailSender.send(msg);
} catch (MailException ex) {
System.err.println(ex.getMessage());
}
}
public void sendFileMail() throws MessagingException {
JavaMailSender mailSender2= (JavaMailSender) mailSender;
MimeMessage message= mailSender2.createMimeMessage();
message.setSubject("spring_mail");
// 創(chuàng)建帶有附件的消息幫組類
MimeMessageHelper helper = new MimeMessageHelper(message,true,"utf-8");
helper.setTo(new InternetAddress("shsxt_test01@163.com"));//設(shè)置接收人
helper.setText("Thank you for ordering!");
helper.setFrom("shsxt_test01@163.com");
helper.addAttachment("28期.bmp", new File("E:\\java_28\\spring08-mail\\28期.bmp"));
mailSender2.send(message);
}
}
4.測(cè)試效果SimpleOrderMangerTest
public class SimpleOrderManagerTest {
@Test
public void placeOrder() throws Exception {
ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");
OrderManager orderManager= (OrderManager) ac.getBean("orderManager");
orderManager.placeOrder();
}
/**
* 發(fā)送附件spring-mail
* @throws Exception
*/
@Test
public void placeOrder02() throws Exception {
ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");
JavaMailSender mailSender= (JavaMailSender) ac.getBean("mailSender");
MimeMessage message= mailSender.createMimeMessage();
message.setSubject("spring_mail_file");
// 創(chuàng)建帶有附件的消息幫組類
MimeMessageHelper helper = new MimeMessageHelper(message,true,"utf-8");
helper.setTo(new InternetAddress("shsxt_test01@163.com"));//設(shè)置接收人
helper.setText("Thank you for ordering!");
helper.setFrom("shsxt_test01@163.com");
helper.addAttachment("pom.xml", new File("E:\\java_28\\spring07mail\\pom.xml"));
mailSender.send(message);
}
}