Spring Boot笔记(七) springboot 集成 JavaMail 实现邮箱认证

Stella981
• 阅读 663

个人博客网: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)邮件收发过程的介绍:

Spring Boot笔记(七) springboot 集成 JavaMail 实现邮箱认证

邮件的发送、接受,在客户端软件中,由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依赖

Spring Boot笔记(七) springboot 集成 JavaMail 实现邮箱认证

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

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解2016年09月02日00:00:36 \牧野(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fme.csdn.net%2Fdcrmg) 阅读数:59593
Wesley13 Wesley13
3年前
Java获得今日零时零分零秒的时间(Date型)
publicDatezeroTime()throwsParseException{    DatetimenewDate();    SimpleDateFormatsimpnewSimpleDateFormat("yyyyMMdd00:00:00");    SimpleDateFormatsimp2newS
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这