Spring02-模拟用户登录,发送邮件
一.注解方式注入 bean
对于 bean 的注入,除了使用 xml 配置以外,注解的配置简化开发的速度,使程
序看上去更简洁。对于注解的解释,spring
对于注解有专门的解释器,对定义的注解
进行解析,实现对应 bean 对象的注入,反射技术实现。
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/>
对于 bean 的注入常用注解类型
@Autowired 属性字段或 set 方法上
@Resource 属性字段上或 set 方法上
区别: @Autowired 默认按 bean 的类型匹配 可以修改 按名称匹配 和
@Qualifier 配合使用
@Resource 默认按名称进行装配, 名称可以通过 name 属性进行指定, 如果没
有指定 name 属性, 当注解写在字段上时, 默认取字段名进行匹配注入, 如果
注解写在 setter 方法上默认取属性名进行装配。 当找不到与名称匹配的 bean
时才按照类型进行装配。 但是需要注意的是,如果 name 属性一旦指定,
就只会按照名称进行装配。
推荐使用@Resource 注解是属于 J2EE 的,减少了与 spring 的耦合。
二、 Spring Ioc 容器自动扫描管理 bean
实际的开发中,bean 的数量非常多,采用手动配置 bean 的方式已无法满足生
产需要,spring 这时候同样提供了扫描的方式,对扫描到的 bean
对象统一进行管理,
简化开发配置,提高开发效率。
<context:component-scan base-package="com.shsxt"/>
**不需要再配置
<context:annotation-config/>
同时对于被 spring 管理的 bean 类的定义上需要加入对应的注解定义
开发中建议(开发中的一种约定)
Dao 层:@Repository
Service 层:@Service
视图控制层:@Controller
如果对于开发的类实在不明确到底属于哪个层,可以使用@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 层 根据用户名查询用户记录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 业务判断处理UserService调用Dao层,进行参数校验
@Service
public class UserService {
@Autowired
private UserDao userDao;
public ResultInfo login(String name, String pwd){
/**
* 1. 参数校验
* 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.定义业务处理返回消息模型新建model包ResultInfo存储查询信息
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调用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 进行测试UserControllerTest测试类
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"));
}
测试结果

四、 Bean 的作用域问题
默认情况下,我们从 spring 容器中拿到的对象均是单例的,对于 bean
的作用
域类型如下:
1、 singleton 作用域

注意: lazy-init 是懒加载, 如果等于 true 时作用是指 spring
容器启动的时候不
会去实例化这个 bean, 而是在程序调用时才去实例化. 默认是 false 即 spring
容器启\动时实例化.
默认情况下,被管理的 bean 只会 IOC 容器中存在一个实例,对于所有获取该
Bean 的操作 Spring 容器将只返回同一个 Bean。
**容器在启动的情况下就实例化所有 singleton 的 bean 对象,并缓存与容器中
单例的好处:
1)提前发现潜在的配置问题
2)Bean 对象存在于缓存中,使用时不用再去实例化 bean,加快程序运行效率
**什么类型的对象适合作为单例对象来使用呢? service,dao,action 等
一般来说对于无状态或状态不可改变的
对象适合使用单例模式(什么是无状态或状态
不可改变)
实际上对象状态的变化往往均是由于属性值得变化而引起的,比如 user 类 年龄
属性会有变化 属性年龄的变化一般会引起 user
对象状态的变化。对于我们的程序来
说,无状态对象 没有实例变量的存在,保证了线程的安全性,service
层业务对象即是
无状态对象。线程安全的。
2、 prototype 作用域

通过 scope=" prototype" 设置 bean 的类型 ,每次向 Spring 容器请求获取
Bean 都返回一个全新的 Bean,相对于"singleton"来说就是不缓存
Bean,每次都是
一个根据 Bean 定义创建的全新 Bean。
<bean id="userController" class="com.shsxt.controller.UserController" scope="prototype"></bean>
不是单例
3、 Web 应用中的作用域(request、 session、 globalsession)
request 作用域:表示每个请求需要容器创建一个全新 Bean。比如提交表单
的数据必须是对每次请求新建一个 Bean
来保持这些表单数据,请求结束释放这些数据。
session 作用域:表示每个会话需要容器创建一个全新
Bean。比如对于每个用
户一般会有一个会话,该用户的用户信息需要存储到会话中,此时可以将该 Bean
作用
域配置为 session 级别。
globalSession:类似于 session 作用域,其用于 portlet(Portlet 是基于
Java
的 Web 组件,由 Portlet 容器管理,并由容器处理请求,生产动态内容)环境的
web 应
用。如果在非 portlet 环境将视为 session 作用域。
配置方式和基本的作用域相同,只是必须要有 web 环境支持,并配置相应的
容器监听器或拦截器从而能应用这些作用域.
五、 Bean 的生命周期
1.Bean 的定义
对比已经学过的 servlet 生命周期(容器启动装载并实例化 servlet
类,初始化
servlet,调用 service 方法,销毁 servlet)。
同样对于 spring 容器管理的 bean 也存在生命周期的概念
**在 Spring 中,Bean 的生命周期包括 Bean 的定义、初始化、使用和销毁 4
个阶段
**在 Spring 中,通常是通过配置文档的方式来定义 Bean
的。在一个配置文档中,可以
定义多个 Bean。
2、 Bean 的初始化
Spring bean 初始化有两种方式:
I.在配置文档中通过指定 init-method 属性来完成。
II.实现 org.springframework.beans.factory.InitializingBean 接口。
Bean 对象实例化过程是在 spring 容器初始化 时被实例化的,但也不是不可改
变的,可以通过 lazy-init="true" 属性延迟 bean
对象的初始化操作,此时再调用
getbean 方法时才会进行 bean 的初始化操作
<bean id="userServiceImpl"class="com.shsxt.service.impl.UserServiceImpl"
init-method="init" >
3.Bean 的使用
I.使用 BeanFactory
II.使用 ApplicationContext
4.Bean 的销毁
实现销毁方式(spring 容器会维护 bean 对象的管理,可以指定 bean 对象的销
毁所要执行的方法)\
<bean id="userServiceImpl"class="com.shsxt.service.impl.UserServiceImpl" init
method="init" destroy-method="destroy">
</bean>
通过 AbstractApplicationContext 对象,调用其 close 方法实现 bean
的销毁过程。\
AbstractApplicationContext ctx=new ClassPathXmlApplicationContext("spring
application.xml");
ctx.close();
六、 JavaMail 概述
JavaMail 是由 Sun 定义的一套收发电子邮件的 API, 不同的厂商可以提供自
己的实现类。 但它并没有包含在 JDK 中, 而是作为 JavaEE 的一部分。
厂商所提供的 JavaMail 服务程序可以有选择地实现某些邮件协议, 常见的
邮件协议包括:
SMTP: 简单邮件传输协议, 用于发送电子邮件的传输协议;
POP3: 用于接收电子邮件的标准协议;
IMAP: 互联网消息协议, 是 POP3 的替代协议。
这三种协议都有对应 SSL 加密传输的协议, 分别是 SMTPS, POP3S 和 IMAPS。
除 JavaMail 服务提供程序之外,JavaMail 还需要 JAF(JavaBeans Activation
Framework)来处理不是纯文本的邮件内容, 这包括 MIME(多用途互联网邮件扩
展 ) 、 URL 页 面 和 文 件 附 件 等 内 容 。 另 外 , JavaMail 依 赖
JAF(JavaBeans
Activation Framework), JAF 在 Java6 之后已经合并到 JDK 中, 而 JDK5
之前需
要另外下载 JAF 的类库。
[6.1、 协议介绍]{.smallcaps}
1、 介绍
在研究 JavaMail API 的细则之前, 首先需要对于 API 用到的协议有个认识。
对于 java mail 来说用到的协议有一下 4 种:
SMTP
POP
IMAP
MIME
2、 SMTP
简单邮件传输协议(Simple Mail Transfer Protocol, SMTP) 由 RFC 821
定义。
它定义了发送电子邮件的机制。 在 JavaMail API 环境中, 您基于 JavaMail
的程
序将和您的公司或因特网服务供应商的(Internet Service Provider's,
ISP's)
SMTP 服务器通信。 SMTP 服务器会中转消息给接收方 SMTP 服务器以便最终让
用户经由 POP 或 IMAP 获得。
3、 POP
POP 代表邮局协议(Post Office Protocol) 。 目前用的是版本 3, 也称
POP3,
RFC 1939 定义了这个协议。 POP 是一种机制,
因特网上大多数人用它得到邮件。
它规定每个用户一个邮箱的支持。 这就是它所能做的,
而这也造成了许多混淆。
使用 POP3 时, 用户熟悉的许多性能并不是由 POP 协议支持的, 如查看有几封
新邮件消息这一性能。 这些性能内建于如 Eudora 或 Microsoft Outlook
之类的程
序中, 它们能记住一些事, 诸如最近一次收到的邮件,
还能计算出有多少是新的。
所以当使用 JavaMail API 时, 如果您想要这类信息, 您就必须自己算。
4、 IMAP
IMAP 是更高级的用于接收消息的协议。 在 RFC 2060 中被定义, IMAP 代表
因特网消息访问协议(Internet Message Access Protocol) , 目前用的是版本
4,
也称 IMAP4。 在用到 IMAP 时, 邮件服务器必需支持这个协议。 不能仅仅把使
用 POP 的程序用于 IMAP, 并指望它支持 IMAP 所有性能。 假设邮件服务器支
持 IMAP, 基于 JavaMail 的程序可以利用这种情况 ---
用户在服务器上有多个文
件夹(folder) , 并且这些文件夹可以被多个用户共享。
因为有这一更高级的性能, 您也许会认为所有用户都会使用 IMAP。 事实并
不是这样。 要求服务器接收新消息, 在用户请求时发送到用户手中,
还要在每个
用户的多个文件夹中维护消息。 这样虽然能将消息集中备份,
但随着用户长期的
邮件夹越来越大, 到磁盘空间耗尽时, 每个用户都会受到损失。 使用 POP,
就能
卸载邮件服务器上保存的消息了。
5、 MIME
MIME 代表多用途因特网邮件扩展标准(Multipurpose Internet Mail
Extensions) 。 它不是邮件传输协议。 但对传输内容的消息、
附件及其它的内容
定义了格式。这里有很多不同的有效文档: RFC 822、RFC 2045、RFC 2046 和
RFC
2047。 作为一个 JavaMail API 的用户, 您通常不必对这些格式操心。
无论如何,
一定存在这些格式而且程序会用到它。
[6.3、 JavaMail 的关键对象]{.smallcaps}
JavaMail 对收发邮件进行了高级的抽象, 形成了一些关键的的接口和类,
它们构成了程
序的基础, 下面我们分别来了解一下这些最常见的对象。
Properties:属性对象
由于 JavaMail 需要和邮件服务器进行通信, 这就要求程序提供许多诸如服务
器地址、 端口、 用户名、 密码等信息, JavaMail 通过 Properties
对象封装这些属
性西信息。 如下面的代码封装了两个属性信息:
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.sina.com.cn");
props.put("mail.smtp.auth", "true");
针对不同的的邮件协议, JavaMail 规定了服务提供者必须支持一系列属性,
下表是针对 SMTP 协议的一些常见属性(属性值都以 String 类型进行设置,
属性
类型栏仅表示属性是如何被解析的) :

其他几个协议也有类似的一系列属性, 如 POP3 的 mail.pop3.host、
mail.pop3.port 以及\IMAP 的 mail.imap.host、 mail.imap.port 等。
Session:会话对象
Session 是一个很容易被误解的类, 这归咎于混淆视听的类名。
千万不要以为这
里的 Session 像 HttpSession 一样代表真实的交互会话, 但创建 Session
对象时,
并没有对应的物理连接, 它只不过是一对配置信息的集合。 Session
的主要作用
包括两个方面:
1) 接收各种配置属性信息: 通过 Properties 对象设置的属性信息;
2) 初始化 JavaMail 环境: 根据 JavaMail 的配置文件, 初始化 JavaMail
环境,
以便通过 Session 对象创建其他重要类的实例。
Transport 和 Store:传输和存储
邮 件 操 作 只 有 发 送 或 接 收 两 种 处 理 方 式 , JavaMail 将 这 两
种 不 同 操 作 描 述 为 传 输
(javax.mail.Transport) 和存储(javax.mail.Store) ,
传输对应邮件的发送, 而存储对应邮件
的接收。
Message:消息对象
一旦获得 Session 对象, 就可以继续创建要发送的消息。 这由 Message
类来完成。 因
为 Message 是个抽象类, 您必需用一个子类, 多数情况下为
javax.mail.internet.MimeMessage。
MimeMessage 是个能理解 MIME 类型和头的电子邮件消息, 正如不同 RFC
中所定义的。 虽
然在某些头部域非 ASCII 字符也能被译码, 但 Message 头只能被限制为用
US-ASCII 字符。
Address:地址
一旦您创建了 Session 和 Message, 并将内容填入消息后, 就可以用 Address
确
定信件地址了。 和 Message 一样, Address 也是个抽象类。 您用的
是 javax.mail.internet.InternetAddress 类。
若创建的地址只包含电子邮件地址, 只要传递电子邮件地址到构造器就行了。
Authenticator:认证者
与 java 类一样, JavaMail API 也可以利用 Authenticator
通过用户名和密码访
问受保护的资源。 对于 JavaMail API 来说, 这些资源就是邮件服务器。
JavaMail
Authenticator 在 javax.mail 包中, 而且它和 java.net 中同名的类
Authenticator 不
同。 两者并不共享同一个 Authenticator, 因为 JavaMail API 用于 Java
1.1, 它没
有 java.net 类别。 要使用 Authenticator, 先创建一个抽象类的子类, 并
从 getPasswordAuthentication() 方法中返回 PasswordAuthentication 实例。
创建完
成后, 您必需向 session 注册 Authenticator。 然后, 在需要认证的时候,
就会通
知 Authenticator。 您可以弹出窗口,
也可以从配置文件中(虽然没有加密是不安
全的) 读取用户名和密码, 将它们作为 PasswordAuthentication
对象返回给调用
程序。
[6.4、 Java mail 发送邮件 环境准备]{.smallcaps}
1.jar 下载
通过 java mail 发送邮件, 首先需要下载对应 Java mail jar 包 下载地址:
http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-eeplat-419426.html#javamail-1.4.5-oth-JPR
2.个人邮箱准备这里以(163 邮箱为例)
注册 163 邮箱, 登录 163 邮箱后 设置邮箱账户开通 smtp 协议

登录到邮箱后 获取邮箱客户端授权码这里需要根据注册时输入的手机后输入 163
服务器发送的验证码来开通, 开通成功
记住个人授权访问码会以短信通知到对应手机, 该授权码是后面通过 Java mail
发送邮件的认证密码 非常重要 不要记错.

6.5、 Java mail 邮件发送实现

1.发送普通文本邮件
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 上下文环境 支持 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
</dependencies>
<build>
</build>
</project>
2)创建认证类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)创建发送类SendMail.java
public class SendMail {
public void send01() throws MessagingException {
//1.設置邮件服务器参数
//定义邮箱服务器配置
Properties props =new Properties();
//163邮件服务器地址
props.put("mail.smtp.host","smtp.163.com");
// 163 邮件服务器端口
props.put("mail.smtp.port", "25");
// 163 邮件服务器认证属性
props.put("mail.smtp.auth", "true");
//2创建session
Session session =Session.getInstance(props,
new MyAuthenticator("13255123823@163.com","why111"));
//3.定义消息
Message message =new MimeMessage(session);
//设置发件人和收件人
message.setFrom(new InternetAddress("13255123823@163.com"));
message.setRecipient(Message.RecipientType.TO,new InternetAddress("286763969@qq.com"));
message.setSentDate(new Date());//发送日期
message.setSubject("第一封邮件"); //发送主题
message.setText("hello, 欢迎你的回复!"); //发送内容
//4.发送
Transport.send(message);
}
4)创建单元测试类SendMailTest类发送邮件
public class SendMailTest {
@Test
public void send01() throws MessagingException {
new SendMail().send01();
System.out.println("发送了一封邮件");
}
执行测试 发送成功 后 进入邮箱查看邮件 .

2.发送 html 邮件内容和发送带附件的内容
1)sendMail类中添加新的方法
/**
* 发送html邮件
* @throws MessagingException
*/
public void send02() throws MessagingException {
//1.設置邮件服务器参数
//定义邮箱服务器配置
Properties props =new Properties();
//163邮件服务器地址
props.put("mail.smtp.host","smtp.163.com");
// 163 邮件服务器端口
props.put("mail.smtp.port", "25");
// 163 邮件服务器认证属性
props.put("mail.smtp.auth", "true");
//2创建session
Session session =Session.getInstance(props,
new MyAuthenticator("13255123823@163.com","why111"));
//3.定义消息
Message message =new MimeMessage(session);
//设置发件人和收件人
message.setFrom(new InternetAddress("13255123823@163.com"));
message.setRecipient(Message.RecipientType.TO,new InternetAddress("286763969@qq.com"));
message.setSentDate(new Date());//发送日期
message.setSubject("html邮件"); //发送主题
//html邮件
MimeMultipart multipart =new MimeMultipart();
MimeBodyPart bodyPart =new MimeBodyPart();
bodyPart.setContent(
"<html><body><a href='http://www.baidu.com'>百度一下</a></body></html>",
"text/html;charset=utf-8");
multipart.addBodyPart(bodyPart);
message.setContent(multipart);
//4.发送
Transport.send(message);
}
/**
* 发送附件邮件
* @throws MessagingException
*/
public void send03() throws MessagingException, UnsupportedEncodingException {
//1.設置邮件服务器参数
//定义邮箱服务器配置
Properties props =new Properties();
//163邮件服务器地址
props.put("mail.smtp.host","smtp.163.com");
// 163 邮件服务器端口
props.put("mail.smtp.port", "25");
// 163 邮件服务器认证属性
props.put("mail.smtp.auth", "true");
//2创建session
Session session =Session.getInstance(props,
new MyAuthenticator("13255123823@163.com","why111"));
//3.定义消息
Message message =new MimeMessage(session);
//设置发件人和收件人
message.setFrom(new InternetAddress("13255123823@163.com"));
message.setRecipient(Message.RecipientType.TO,new InternetAddress("286763969@qq.com"));
message.setSentDate(new Date());//发送日期
message.setSubject("带附件邮件"); //发送主题
//html邮件
MimeMultipart multipart =new MimeMultipart();
MimeBodyPart bodyPart =new MimeBodyPart();
bodyPart.setContent(
"<html><body><a href='http://www.baidu.com'>百度一下</a></body></html>",
"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"));
//设置附件
bodyPart02.setDataHandler(new DataHandler(fds));
//设置文件名
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"));
//设置附件
bodyPart3.setDataHandler(new DataHandler(fds2));
//设置文件名
bodyPart3.setFileName(MimeUtility.encodeText("11.jpg"));
multipart.addBodyPart(bodyPart3);
message.setContent(multipart);
//4.发送
Transport.send(message);
}
}
2)SendMailTest类发送html邮件
public class SendMailTest {
@Test
public void send01() throws MessagingException {
new SendMail().send01();
System.out.println("发送了一封邮件");
}
@Test
public void send02() throws MessagingException {
new SendMail().send02();
System.out.println("发送了html邮件");
}
@Test
public void send03() throws Exception {
new SendMail().send03();
System.out.println("发送了附件邮件");
}
测试结果

3Java mail 邮件发送封装\
1)邮件发送器方法封装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;
/**
* 简单封装邮件发送器 发送邮件实现
* @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 邮件服务器地址
props.put("mail.smtp.host", mailSendInfo.getServerHost());
// 163 邮件服务器端口
props.put("mail.smtp.port",mailSendInfo.getServerPort());
// 163 邮件服务器认证属性
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);// 设置接收人地址
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()));//设置文件名
multipart.addBodyPart(temp);//添加附件
}
}
}
// 设置邮件内容
message.setContent(multipart);
Transport.send(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
2)邮件发送信息类简单封装ShSxtMailSendInfo
package com.shsxt.util;
import java.util.List;
/**
* 邮件发送信息类
* 定义发送邮件时 邮件服务器 端口 发送方用户名 密码等字段
* @author lp
*
*/
public class ShSxtMailSendInfo {
private String serverHost;// 服务器主机
private String serverPort;//服务器端口
private String fromAddress;//发送方邮箱地址
private List<String> toAddress;// 接收方邮箱地址
private String userName;//邮件服务器用户名
private String userPwd;//邮件服务器密码
private String subject;//邮件主题
private String content;// 邮件内容
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)测试SendMailTest类发送 html和附件邮件
/**
* 邮件发送封装
*/
@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);
}
/**
* 封装后发送带附件邮件测试
*/
@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 实现邮件发送
1.环境准备
这里建立 maven 普通工程

添加坐标依赖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 上下文环境 支持 -->
<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.配置文件配置邮件发送 bean
借助 spring 环境配置邮件发送相关 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>
<!-- 配置定时任务 -->
<!-- 通过注解 -->
<!-- 开启定时任务注解 -->
<task:annotation-driven />
<bean id="myJob02" class="com.shsxt.task.MyJob02"></bean>
</beans>
3.发送接口定义与实现
package-orderManger接口
/**
* 发送邮件接口定义
* @author lp
*
*/
public interface OrderManager {
void placeOrder();
}
package-SimpleorderManger实现类
**
* 接口实现类
*/
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");
// 创建带有附件的消息帮组类
MimeMessageHelper helper = new MimeMessageHelper(message,true,"utf-8");
helper.setTo(new InternetAddress("shsxt_test01@163.com"));//设置接收人
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.测试效果SimpleOrderMangerTest
public class SimpleOrderManagerTest {
@Test
public void placeOrder() throws Exception {
ApplicationContext ac=new ClassPathXmlApplicationContext("spring.xml");
OrderManager orderManager= (OrderManager) ac.getBean("orderManager");
orderManager.placeOrder();
}
/**
* 发送附件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");
// 创建带有附件的消息帮组类
MimeMessageHelper helper = new MimeMessageHelper(message,true,"utf-8");
helper.setTo(new InternetAddress("shsxt_test01@163.com"));//设置接收人
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);
}
}