个人博客网:https://wushaopei.github.io/    (你想要这里多有)

一、JavaMail

1、什么是JavaMail?

JavaMail,顾名思义,提供给开发者处理 电子邮件相关的编程接口。它是Sun发布的用来处理email的API。它可以方便的执行一些常用的邮件传输。我们可以基于JavaMaiil开发出类似于 Microsoft Outlook的应用程序。

2、关于要使用JavaMail的原因?

基于现在WEB开发中对JavaMail的需求,例如:

用户注册后,网站发送一封激活邮件验证;

用户过生日,系统发送生日祝福邮件;

将最新活动和优惠以邮件的形式告知会员等等........

以上的需求都需要通过编程语言实现发送邮件功能,而JavaMail便能满足这一需求。

3、电子邮箱及邮件服务器

什么是电子邮箱?

  电子邮箱(E-mail 地址) 需要在邮件服务器上进行申请,确切的说,电子邮箱其实就是用户在邮件服务器上申请的一个账户,用户在邮件服务器上申请了一个账号后,邮件服务器就会为这个账号分配一定的空间,用户从而可以使用这个账号以及空间,发送电子邮件和保存别人发送过来的电子邮件。

什么是邮箱服务器?

服务器指的是一台电脑安装了一个服务器软件,那么这台电脑就可以称为是WEB服务器,那么同样的一台电脑安装了邮件服务器软件,那么这台电脑称为是邮件服务器

基于互联网的电子邮件功能:

要在Internet上提供电子邮件功能,必须有专门的电子邮件服务器,例如目前网络上提供邮件服务的厂商:新浪、搜狐、网易等等他们都有自己的邮件服务器

4、邮件收发协议

(1)SMTP协议(发送邮件)

 简单邮件传输协议 (Simple Mail Transfer Protocol, SMTP) 是在Internet传输email事实标准。(百度百科)

SMTP是一个相对简单的基于文本协议。在其之上指定了一条消息的一个或多个接收者(在大多数情况下被确认是存在的),然后消息文本会被传输。可以很简单地通过telnet程序来测试一个SMTP服务器。SMTP使用TCP端口25。要为一个给定的域名决定一个SMTP服务器,需要使用MX (Mail eXchange) DNS。(百度百科)

用户脸上邮件服务器后,要想给它发送一封电子邮件,需要遵循一定的通讯规则,SMTP协议就是用于定义这种规则的。因此,通常我们也把处理用户SMTP请求(邮件发送请求)的邮件服务器称之为SMTP服务器。

(2)POP3协议(接收邮件)

POP3,全名为“Post Office Protocol - Version 3”,即“邮局协议版本3”。是TCP/IP协议族中的一员,由RFC1939 定义。本协议主要用于支持使用客户端远程管理在服务器上的电子邮件。提供了SSL加密的POP3协议被称为POP3S。(百度百科)

POP 协议支持“离线”邮件处理。其具体过程是:邮件发送到服务器上,电子邮件客户端调用邮件客户机程序以连接服务器,并下载所有未阅读的电子邮件。这种离线访问模式是一种存储转发服务,将邮件从邮件服务器端送到个人终端机器上,一般是PC机或 MAC。一旦邮件发送到 PC 机或MAC上,邮件服务器上的邮件将会被删除。但目前的POP3邮件服务器大都可以“只下载邮件,服务器端并不删除”,也就是改进的POP3协议。(百度百科)

同样,用户若想从邮件服务器管理的电子邮件中接受一封电子邮件的话,他脸上邮件服务器后,也需要遵循一定的通讯格式,POP3协议用于定义这种通讯格式。

因而,通常我们也把处理用户POP3请求(邮件接受请求)的邮件服务器称之为POP3服务器。

(3)邮件收发过程的介绍:

邮件的发送、接受,在客户端软件中,由SMTP服务器进行发送操作,接受是由POP3服务器进行接收。

1、邮件发送协议-SMTP,默认端口号25

用于把用户邮件从一个服务器转到下一个服务器

2、邮件接收协议-POP3,默认端口号110

用于支持使用客户端远程管理在服务器上的电子邮件

二、邮件发送代码实现

1、环境搭建

(1)创建数据库和表

CREATE TABLE `NewTable` (
`uid` int(11) NOT NULL AUTO_INCREMENT ,
`username` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`password` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`nickname` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`email` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`state` int(11) NULL DEFAULT NULL ,
`code` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
PRIMARY KEY (`uid`)
)
ENGINE=InnoDB
DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
AUTO_INCREMENT=22
ROW_FORMAT=DYNAMIC
;

(2)创建一个springboot工程,创建相应的包,并配置相应的pom.xml依赖

pom.xml

	<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency> <dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<!--<version>5.1.41</version> -->
<version>8.0.13</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
<!-- lombok 简化 java 代码 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency> <!--郵箱發送--> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>

(3)创建User类并配置application.yml

User类:

@Data
public class User { private Integer uid;
private String username;
private String password;
private String nickname;
private String email;
private Integer state;
private String code; }

application.yml

server:
port: 80 spring:
datasource:
url: jdbc:mysql://localhost:3333/regist_web?useUnicode=true&characterEncoding=utf-8&useSSL=false&autoReconnect=true&serverTimezone=UTC
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
mapper-locations: classpath*:/mybatis/mappers/*Mapper.xml
type-aliases-package: com.entities #邮件配置(发件人)
email:
host: smtp.163.com
username: 1***9746***@163.com
password: 1***9746**
senderName: 1***9746***@163.com

(4)设计注册页面

index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="jquery-1.11.3.js"></script>
</head>
<body>
<h1>用户注册的页面</h1>
<form action="/get/getParam/user" method="get">
<table width="600" border="1">
<tr>
<td>用户名</td>
<td><input type="text" name="username"/></td>
</tr>
<tr>
<td>密码</td>
<td><input type="password" name="password"/></td>
</tr>
<tr>
<td>昵称</td>
<td><input type="text" name="nickname"/></td>
</tr>
<tr>
<td>邮箱</td>
<td><input type="text" name="email"/></td>
</tr>
<tr> <td colspan="2"><input type="submit" value="注册"/></td>
</tr>
</table>
</form>
</body>
</html>

(5)Handler :创建接口,接收form 表单数据并进行封装,并经过dao 层 添加到对应的数据库表中

@ResponseBody
@RequestMapping ("/get/getParam/user")
public Object getParam(@RequestParam("username")String username,
@RequestParam("password")String password,
@RequestParam("nickname")String nickname,
@RequestParam("email")String email,
HttpServletRequest request
) {
Map<String,Object> map = null;
try {
request.setCharacterEncoding("UTF-8"); if(username.equals("") && password.equals("") && nickname.equals("") && email.equals("")){ return "请不要留空";
}
//封装数据
User user = new User();
user.setUsername(username);
user.setPassword(password);
user.setNickname(nickname);
user.setEmail(email);
user.setState(0);// 0 : 未激活 1: 已经激活 //使用 UUID 随机生成激活码
String code = UUIDUtils.getUUID()+ UUIDUtils.getUUID();
user.setCode(code); map = new HashMap<>();
//调用业务层处理数据
userService.addUser(user); map.put("state","0");
map.put("message", "發送成功");
//页面跳转
} catch (Exception e) {
//
map.put("state","1");
map.put("message", "發送失敗");
e.printStackTrace();
throw new RuntimeException();
}
return map;
}

(6)创建一个UUIDUtils 工具类,使用UUID随机生成激活码

/**
* @ClassName UUIDUtils 生成随机字符串工具类
* @Description TODO
* @Author wushaopei
* @Date 2019/9/8 13:52
* @Version 1.0
*/ public class UUIDUtils { public static String getUUID(){
return UUID.randomUUID().toString().replace("-","");
}
}

(7)创建邮箱参数实体EmailConfig.java和发送邮件工具类MailUtils.java

EmailConfig.java

package com.utils;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource; /**
* @ClassName EmailConfig
* @Description TODO
* @Author wushaopei
* @Date 2019/7/25 10:24
* @Version 1.0
*/
@Configuration
@ConfigurationProperties(prefix = "email", ignoreUnknownFields = false)
//@PropertySource("classpath:/application.yml")
public class EmailConfig {
private String host;
private String username;
private String password;
private String senderName; public String getHost() {
return host;
} public void setHost(String host) {
this.host = host;
} public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} public String getSenderName() {
return senderName;
} public void setSenderName(String senderName) {
this.senderName = senderName;
} @Override
public String toString() {
return "EmailConfig{" +
"host='" + host + '\'' +
", username='" + username + '\'' +
", password='" + password + '\'' +
", senderName='" + senderName + '\'' +
'}';
}
}

MailUtils.java

package com.utils;

import com.mysql.cj.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component; import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.util.Properties; /**
* @ClassName MailUtils
* @Description TODO
* @Author wushaopei
* @Date 2019/9/8 14:49
* @Version 1.0
*/
@Component
public class MailUtils { @Autowired
private EmailConfig emailConfig; private final Logger logger = LoggerFactory.getLogger(MailUtils.class);
/**
* 发送邮件的方法
* @Param to :给谁发邮件
* @Param code : 邮件的激活码
* @Param subject : 主题
* @Param text : 内容
*
*/
public void sendMail(String toEmail, String code,final String subject,final String text){
try{
//1、创建邮件对象
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
//2、发邮件人邮箱
javaMailSender.setUsername(emailConfig.getUsername());
//3、发邮件人邮箱密码(默认使用客户端的授权码)
javaMailSender.setPassword(emailConfig.getPassword());
//4、设置邮件服务器主机名 SMTP服务器地址
javaMailSender.setHost(emailConfig.getHost());
//5、SMTP服务器: 默认端口
javaMailSender.setPort(25);
//6、//发送邮件协议名称
javaMailSender.setProtocol("smtp");
//7、编码格式
javaMailSender.setDefaultEncoding("UTF-8"); //8、创建连接对象,连接到邮箱服务器
Properties mailProperties = new Properties();
//发送服务器需要身份验证,要采用指定用户名密码的方式去认证
mailProperties.put("mail.smtp.auth", true);
mailProperties.put("mail.smtp.starttls.enable", true); //9、添加连接对象到邮件对象中
javaMailSender.setJavaMailProperties(mailProperties); int count = 1;
//10、创建
//可以发送几封邮件:可以这里 for循环多次
MimeMessage mimeMessage = getMimeMessage(toEmail,subject,text, javaMailSender);
//11、发送邮件
javaMailSender.send(mimeMessage);
logger.info("发送 第"+ count + "封邮件" );
count ++; logger.info("发往 "+toEmail+" 邮件发送成功");
} catch (MessagingException e) {
logger.error("发往 "+toEmail+" 邮件发送异常", e);
}
} //声明一个Message对象(代表一封邮件),从session中创建
private MimeMessage getMimeMessage(String toEmail,String subject,String text, JavaMailSenderImpl javaMailSender) throws MessagingException { MimeMessage mimeMessage = javaMailSender.createMimeMessage(); MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
//发件人
mimeMessageHelper.setFrom(emailConfig.getSenderName());
//收件人 : 可以发送给多个收件人,该方法有一个重载的 数组形参
mimeMessageHelper.setTo(toEmail);
// mimeMessage.setContent(); //邮件主题
mimeMessageHelper.setSubject(subject);
//邮件内容
mimeMessageHelper.setText(text, true); return mimeMessage;
}
}

(8)在(4)中的接口接收注册参数并写入数据库后,进行激活邮件的发送

        //调用业务层处理数据
userService.addUser(user);

UserServiceimpl.java

        @Override
public Integer addUser(User user) { //将数据存入到数据库
Integer integer = userMapper.addUser(user); //发送一封激活邮件
mailUtils.sendMail("18620307785@163.com",user.getCode(),"来自邮箱测试接口邮件","<h1>来自wto网站激活邮件,激活请点击以下链接:</h1><h3><a href='http://wj7ei8.natappfree.cc/regist_web/activateServlet?code="+user.getCode()+"'>http://wj7ei8.natappfree.cc/regist_web/activateServlet?code="+user.getCode()+"</a></h3>"); return integer;
}

完整 业务层代码:

UserService.java


public interface UserService { List<User> getAll(); Integer addUser(User user); User findByCode(String code); void updateUser(User user);
}

UserServiceImpl.java


@Service
public class UserServiceImpl implements UserService { @Autowired
private UserMapper userMapper; @Autowired
private MailUtils mailUtils; public List<User> getAll() {
return userMapper.selectAll();
} @Override
public Integer addUser(User user) { //将数据存入到数据库
Integer integer = userMapper.addUser(user); //发送一封激活邮件
mailUtils.sendMail("18620307785@163.com",user.getCode(),"来自邮箱测试接口邮件","<h1>来自wto网站激活邮件,激活请点击以下链接:</h1><h3><a href='http://wj7ei8.natappfree.cc/regist_web/activateServlet?code="+user.getCode()+"'>http://wj7ei8.natappfree.cc/regist_web/activateServlet?code="+user.getCode()+"</a></h3>"); return integer;
} @Override
public User findByCode(String code) { return userMapper.findByCode(code);
} @Override
public void updateUser(User user) {
userMapper.updateUser(user);
} }

(9)UserMapper.java 和 UserMapper.xml

@Component
@Mapper
public interface UserMapper { List<User> selectAll(); Integer addUser(User user); User findByCode(@Param("code") String code); void updateUser(User user);
}

	<select id="selectAll"
resultType="User">
select *
from
user
</select>
<insert id="addUser" parameterType="com.entities.User"
useGeneratedKeys="true"
keyProperty="id" >
INSERT INTO user (
username,
password,
nickname,
email,
state,
code
)
VALUES
(
#{username},
#{password},
#{nickname},
#{email},
#{state},
#{code}
)
</insert> <select id="findByCode"
resultType="com.entities.User">
SELECT
*
FROM
user u
WHERE
u. CODE = #{code}
</select> <update id="updateUser" parameterType="com.entities.User">
UPDATE user
<trim prefix="set" suffixOverrides=",">
<if test="username != null">
username=#{username},
</if>
<if test="password != null">
password=#{password},
</if>
<if test="nickname != null">
nickname=#{nickname},
</if>
<if test="email!=null">
email=#{email},
</if>
state=#{state},
code=#{code}
</trim>
WHERE uid=#{uid}
</update>

(10)创建用户激活接口:

  /*
* 用户激活的 接口
* */
@ResponseBody
@GetMapping("/regist_web/activateServlet")
public Object activateServlet(@RequestParam("code")String code,
HttpServletRequest request,HttpServletResponse response) {
Map<String,Object> map = null;
try {
map = new HashMap<>();
User user = userService.findByCode(code);
if(user != null){
//已经查询到,修改用户的状态
user.setState(1);//已经激活
user.setCode(null);
//激活后修改用户的激活码及状态
userService.updateUser(user);
map.put("state","0");
map.put("message", "您的激活码已激活!请去登录"); }else {
//根据激活码没有查询到该用户
//
map.put("state","0");
map.put("message", "您的激活码有误!请重新激活");
} }catch (Exception e){
e.printStackTrace();
map.put("state","1");
map.put("message", "發送失敗");
throw new RuntimeException();
} return map;
}

小结:

发送激活邮件正文,正文内容使用 html 的语法进行修饰,用户邮箱POP3接受到邮件后会自动根据标签及样式进行解析。

激活邮件的原理:

发送邮件给用户,用户根据接收到的邮件的连接点击并跳转到对应的controller请求接口执行code验证码查询到用户,并根据当前激活码的作用对用户执行激活账户、业务等操作!!!

https://github.com/wushaopei/SPRING_BOOT/tree/master/spring-boot-JSP-email

Spring Boot笔记(七) springboot 集成 JavaMail 实现邮箱认证的更多相关文章

  1. Spring Boot笔记(二) springboot 集成 SMTP 发送邮件

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 笔记:乘着项目迭代的间隙,把一些可复用的功能从项目中抽取出来,这是其中之一, 一.添加SMTP 及 MA ...

  2. Spring Boot笔记(三) springboot 集成 Quartz 定时任务

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 1. 在 pom.xml 中 添加 Quartz 所需要 的 依赖 <!--定时器 quartz- ...

  3. Spring Boot笔记(一) springboot 集成 swagger-ui

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 1.添加依赖 <!--SpringBoot整合Swagger-ui--> <depen ...

  4. Spring Boot笔记(六) springboot 集成 timer 定时任务

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 1.创建具体要执行的任务类: package com.example.poiutis.timer; im ...

  5. Spring Boot笔记(五) SpringBoot 集成Lombok 插件

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 为了减少代码量,为当前项目添加 lombok 来优雅编码 Lombok 插件安装: a . 添加依赖: ...

  6. Spring Boot笔记七:扩展Spring MVC

    新建一个类,继承WebMvcConfigurerAdapter package com.vae.springboot.config; import org.springframework.contex ...

  7. spring boot / cloud (七) 使用@Retryable来进行重处理

    spring boot / cloud (七) 使用@Retryable来进行重处理 前言 什么时候需要重处理? 在实际工作中,重处理是一个非常常见的场景,比如:发送消息失败,调用远程服务失败,争抢锁 ...

  8. spring boot 笔记--第三章

    spring boot 笔记 第三章,使用Spring boot 构建系统: 强烈建议支持依赖管理的构建系统,Maven或Gradle 依赖管理: Spring Boot的每版本都会提供它支持的依赖列 ...

  9. Spring Boot (七): Mybatis极简配置

    Spring Boot (七): Mybatis极简配置 1. 前言 ORM 框架的目的是简化编程中的数据库操作,经过这么多年的发展,基本上活到现在的就剩下两家了,一个是宣称可以不用写 SQL 的 H ...

随机推荐

  1. python地图投影转换

    一.投影包osr与proj4的使用 1.osr投影转换示例 from osgeo import osr,ogr#定义投影#wgs84source=osr.SpatialReference()sourc ...

  2. 标准IDOC同步物料

    目录 1功能说明    4 2功能实现    4 2.1创建逻辑系统并分配集团(SALE)    4 2.2维护RFC目标(SM59)    5 2.3在发送端创建模型视图(BD64)    5 2. ...

  3. java 实现mongoDB 增加,删除,修改,查看,多条件查询,聚合查询,分组查询(史上最全)

    首先idea创建一手springboot项目 引入如下依赖 <dependency> <groupId>org.mongodb</groupId> <arti ...

  4. 网络通信-在浏览器输入url,基于TCP/IP协议,浏览器渲染的解释

    知识点1: 网络模型 TCP/IP四层 和ISO七层模型 (统一省略后面层字.比如传输代表传输层) 知识点2: 在应用层中TCP建立连接,经历的三次握手协议 首先:,TCP协议是什么? 为什么要三次握 ...

  5. PMS学习

    一,PMS的adb相关重要指令 1,adb shell dumpsys package(dump所有的系统内apk信息) 2,adb shell dumpsys package “com.androi ...

  6. zip压缩文件(二)

    普通压缩文件以20M大小的文件为例 public static void main(String[] args) { String source = "F:\\demo\\择天记 第5季 第 ...

  7. Oracle细粒度审计

    场景 管理信息化应用,想审计某张表的数据是否做了删除.Oracle中专门有自带的函数.可以满足这个需求 1.查询审计日志的语句 select timestamp, db_user, os_user, ...

  8. 【遗传编程/基因规划】Genetic Programming

    目录 背景介绍 程序表示 初始化 (Initialization) Depth定义 Grow方法 Full方法 Ramped half-and-half方法 适应度(Fitness)与选择(Selec ...

  9. nginx配置之站点服务请求功能配置

    站点服务请求功能配置:html/ nginx.conf中的http{}中的server{}: server { listen 85; server_name localhost; #charset k ...

  10. python3.x 基础七:面向对象进阶

    类的高级方法: 1.静态方法:在类方法前增加关键字@staticmethod,将普通方法变成静态方法,不能再次传值,不能访问实例变量或者类变量,与类的关系仅仅是通过类名进行调用 2.类方法:在类方法前 ...