个人博客网: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. Spring官网阅读(十八)Spring中的AOP

    文章目录 什么是AOP AOP中的核心概念 切面 连接点 通知 切点 引入 目标对象 代理对象 织入 Spring中如何使用AOP 1.开启AOP 2.申明切面 3.申明切点 切点表达式 excecu ...

  2. 一条SQL的执行流程

  3. 谈谈Spring bean的生命周期(一)

    简介 本片文章主要讲Spring IOC容器中 bean 的生命周期 Spring bean 生命周期 Spring 中bean的声明周期 可以分为如下4个阶段: 实例化阶段--Instantiati ...

  4. Day_08【面向对象】扩展案例4_年龄为30岁的老王养了一只黑颜色的2岁的宠物……

    #分析以下需求,并用代码实现: 1.定义动物类 属性: 年龄,颜色 行为: eat(String something)方法(无具体行为,不同动物吃的方式和东西不一样,something表示吃的东西) ...

  5. [hdu4713 Permutation]DP

    题意:将一个数拆成若干数的和使得它们的最小公倍数最大 思路:一个数x可以拆成p1k1 + p2k2 + ... + pnkn形式,其中pi是质数或1.对于最小公倍数最大的情况,一定可以表示成这种形式. ...

  6. IntelliJ Idea14 创建Maven多模块项目,多继承,热部署配置总结(三)

    pom.xml中repositories.pluginRepository的作用 pom.xml中repositories标签的作用是: 用来配置maven项目的远程仓库.示例如下: <repo ...

  7. 一、线程 & 线程池

    一.线程的介绍 1.1.概念 进程: 你的硬盘上有一个简单的程序,这个程序叫QQ.exe,这是一个程序,这个程序是一个静态的概念,它被扔在硬盘上也没人理他,但是当你双击它,弹出一个界面输入账号密码登录 ...

  8. python100例 11-20

    011 兔子问题 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? f1=1 f2=1 for i ...

  9. Millar Robin模板

    \(Millar Robin\)模板 hdu2138 \(Code\) #include <cstdio> #include <iostream> #include <a ...

  10. css3弹性布局

    二.弹性布局(重点******************************************) 1.什么是弹性布局 弹性布局,是一种布局方式. 主要解决的是某个元素中子元素的布局方式 让页面 ...