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

我不是女神ヾ 2023-08-17 16:28 127阅读 0赞

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

20190928202251483.png

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

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

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

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

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

二、邮件发送代码实现

1、环境搭建

(1)创建数据库和表

  1. CREATE TABLE `NewTable` (
  2. `uid` int(11) NOT NULL AUTO_INCREMENT ,
  3. `username` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
  4. `password` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
  5. `nickname` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
  6. `email` varchar(30) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
  7. `state` int(11) NULL DEFAULT NULL ,
  8. `code` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
  9. PRIMARY KEY (`uid`)
  10. )
  11. ENGINE=InnoDB
  12. DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
  13. AUTO_INCREMENT=22
  14. ROW_FORMAT=DYNAMIC
  15. ;

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

20190928203125865.png

pom.xml

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-web</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-test</artifactId>
  8. <scope>test</scope>
  9. </dependency>
  10. <dependency>
  11. <groupId>mysql</groupId>
  12. <artifactId>mysql-connector-java</artifactId>
  13. <!--<version>5.1.41</version> -->
  14. <version>8.0.13</version>
  15. </dependency>
  16. <dependency>
  17. <groupId>org.mybatis.spring.boot</groupId>
  18. <artifactId>mybatis-spring-boot-starter</artifactId>
  19. <version>1.1.1</version>
  20. </dependency>
  21. <dependency>
  22. <groupId>junit</groupId>
  23. <artifactId>junit</artifactId>
  24. <version>RELEASE</version>
  25. <scope>test</scope>
  26. </dependency>
  27. <!-- lombok 简化 java 代码 -->
  28. <dependency>
  29. <groupId>org.projectlombok</groupId>
  30. <artifactId>lombok</artifactId>
  31. <optional>true</optional>
  32. </dependency>
  33. <!--郵箱發送-->
  34. <dependency>
  35. <groupId>org.springframework.boot</groupId>
  36. <artifactId>spring-boot-starter-mail</artifactId>
  37. </dependency>
  38. <dependency>
  39. <groupId>org.springframework.boot</groupId>
  40. <artifactId>spring-boot-configuration-processor</artifactId>
  41. <optional>true</optional>
  42. </dependency>

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

User类:

  1. @Data
  2. public class User {
  3. private Integer uid;
  4. private String username;
  5. private String password;
  6. private String nickname;
  7. private String email;
  8. private Integer state;
  9. private String code;
  10. }

application.yml

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

(4)设计注册页面

index.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. <script src="jquery-1.11.3.js"></script>
  7. </head>
  8. <body>
  9. <h1>用户注册的页面</h1>
  10. <form action="/get/getParam/user" method="get">
  11. <table width="600" border="1">
  12. <tr>
  13. <td>用户名</td>
  14. <td><input type="text" name="username"/></td>
  15. </tr>
  16. <tr>
  17. <td>密码</td>
  18. <td><input type="password" name="password"/></td>
  19. </tr>
  20. <tr>
  21. <td>昵称</td>
  22. <td><input type="text" name="nickname"/></td>
  23. </tr>
  24. <tr>
  25. <td>邮箱</td>
  26. <td><input type="text" name="email"/></td>
  27. </tr>
  28. <tr>
  29. <td colspan="2"><input type="submit" value="注册"/></td>
  30. </tr>
  31. </table>
  32. </form>
  33. </body>
  34. </html>

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

  1. @ResponseBody
  2. @RequestMapping ("/get/getParam/user")
  3. public Object getParam(@RequestParam("username")String username,
  4. @RequestParam("password")String password,
  5. @RequestParam("nickname")String nickname,
  6. @RequestParam("email")String email,
  7. HttpServletRequest request
  8. ) {
  9. Map<String,Object> map = null;
  10. try {
  11. request.setCharacterEncoding("UTF-8");
  12. if(username.equals("") && password.equals("") && nickname.equals("") && email.equals("")){
  13. return "请不要留空";
  14. }
  15. //封装数据
  16. User user = new User();
  17. user.setUsername(username);
  18. user.setPassword(password);
  19. user.setNickname(nickname);
  20. user.setEmail(email);
  21. user.setState(0);// 0 : 未激活 1: 已经激活
  22. //使用 UUID 随机生成激活码
  23. String code = UUIDUtils.getUUID()+ UUIDUtils.getUUID();
  24. user.setCode(code);
  25. map = new HashMap<>();
  26. //调用业务层处理数据
  27. userService.addUser(user);
  28. map.put("state","0");
  29. map.put("message", "發送成功");
  30. //页面跳转
  31. } catch (Exception e) {
  32. //
  33. map.put("state","1");
  34. map.put("message", "發送失敗");
  35. e.printStackTrace();
  36. throw new RuntimeException();
  37. }
  38. return map;
  39. }

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

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

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

EmailConfig.java

  1. package com.utils;
  2. import org.springframework.boot.context.properties.ConfigurationProperties;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.context.annotation.PropertySource;
  5. /**
  6. * @ClassName EmailConfig
  7. * @Description TODO
  8. * @Author wushaopei
  9. * @Date 2019/7/25 10:24
  10. * @Version 1.0
  11. */
  12. @Configuration
  13. @ConfigurationProperties(prefix = "email", ignoreUnknownFields = false)
  14. //@PropertySource("classpath:/application.yml")
  15. public class EmailConfig {
  16. private String host;
  17. private String username;
  18. private String password;
  19. private String senderName;
  20. public String getHost() {
  21. return host;
  22. }
  23. public void setHost(String host) {
  24. this.host = host;
  25. }
  26. public String getUsername() {
  27. return username;
  28. }
  29. public void setUsername(String username) {
  30. this.username = username;
  31. }
  32. public String getPassword() {
  33. return password;
  34. }
  35. public void setPassword(String password) {
  36. this.password = password;
  37. }
  38. public String getSenderName() {
  39. return senderName;
  40. }
  41. public void setSenderName(String senderName) {
  42. this.senderName = senderName;
  43. }
  44. @Override
  45. public String toString() {
  46. return "EmailConfig{" +
  47. "host='" + host + '\'' +
  48. ", username='" + username + '\'' +
  49. ", password='" + password + '\'' +
  50. ", senderName='" + senderName + '\'' +
  51. '}';
  52. }
  53. }

MailUtils.java

  1. package com.utils;
  2. import com.mysql.cj.Session;
  3. import org.slf4j.Logger;
  4. import org.slf4j.LoggerFactory;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.mail.javamail.JavaMailSenderImpl;
  7. import org.springframework.mail.javamail.MimeMessageHelper;
  8. import org.springframework.stereotype.Component;
  9. import javax.mail.MessagingException;
  10. import javax.mail.internet.MimeMessage;
  11. import java.util.Properties;
  12. /**
  13. * @ClassName MailUtils
  14. * @Description TODO
  15. * @Author wushaopei
  16. * @Date 2019/9/8 14:49
  17. * @Version 1.0
  18. */
  19. @Component
  20. public class MailUtils {
  21. @Autowired
  22. private EmailConfig emailConfig;
  23. private final Logger logger = LoggerFactory.getLogger(MailUtils.class);
  24. /**
  25. * 发送邮件的方法
  26. * @Param to :给谁发邮件
  27. * @Param code : 邮件的激活码
  28. * @Param subject : 主题
  29. * @Param text : 内容
  30. *
  31. */
  32. public void sendMail(String toEmail, String code,final String subject,final String text){
  33. try{
  34. //1、创建邮件对象
  35. JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
  36. //2、发邮件人邮箱
  37. javaMailSender.setUsername(emailConfig.getUsername());
  38. //3、发邮件人邮箱密码(默认使用客户端的授权码)
  39. javaMailSender.setPassword(emailConfig.getPassword());
  40. //4、设置邮件服务器主机名 SMTP服务器地址
  41. javaMailSender.setHost(emailConfig.getHost());
  42. //5、SMTP服务器: 默认端口
  43. javaMailSender.setPort(25);
  44. //6、//发送邮件协议名称
  45. javaMailSender.setProtocol("smtp");
  46. //7、编码格式
  47. javaMailSender.setDefaultEncoding("UTF-8");
  48. //8、创建连接对象,连接到邮箱服务器
  49. Properties mailProperties = new Properties();
  50. //发送服务器需要身份验证,要采用指定用户名密码的方式去认证
  51. mailProperties.put("mail.smtp.auth", true);
  52. mailProperties.put("mail.smtp.starttls.enable", true);
  53. //9、添加连接对象到邮件对象中
  54. javaMailSender.setJavaMailProperties(mailProperties);
  55. int count = 1;
  56. //10、创建
  57. //可以发送几封邮件:可以这里 for循环多次
  58. MimeMessage mimeMessage = getMimeMessage(toEmail,subject,text, javaMailSender);
  59. //11、发送邮件
  60. javaMailSender.send(mimeMessage);
  61. logger.info("发送 第"+ count + "封邮件" );
  62. count ++;
  63. logger.info("发往 "+toEmail+" 邮件发送成功");
  64. } catch (MessagingException e) {
  65. logger.error("发往 "+toEmail+" 邮件发送异常", e);
  66. }
  67. }
  68. //声明一个Message对象(代表一封邮件),从session中创建
  69. private MimeMessage getMimeMessage(String toEmail,String subject,String text, JavaMailSenderImpl javaMailSender) throws MessagingException {
  70. MimeMessage mimeMessage = javaMailSender.createMimeMessage();
  71. MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
  72. //发件人
  73. mimeMessageHelper.setFrom(emailConfig.getSenderName());
  74. //收件人 : 可以发送给多个收件人,该方法有一个重载的 数组形参
  75. mimeMessageHelper.setTo(toEmail);
  76. // mimeMessage.setContent();
  77. //邮件主题
  78. mimeMessageHelper.setSubject(subject);
  79. //邮件内容
  80. mimeMessageHelper.setText(text, true);
  81. return mimeMessage;
  82. }
  83. }

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

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

UserServiceimpl.java

  1. @Override
  2. public Integer addUser(User user) {
  3. //将数据存入到数据库
  4. Integer integer = userMapper.addUser(user);
  5. //发送一封激活邮件
  6. 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>");
  7. return integer;
  8. }

完整 业务层代码:

UserService.java

  1. public interface UserService {
  2. List<User> getAll();
  3. Integer addUser(User user);
  4. User findByCode(String code);
  5. void updateUser(User user);
  6. }

UserServiceImpl.java

  1. @Service
  2. public class UserServiceImpl implements UserService {
  3. @Autowired
  4. private UserMapper userMapper;
  5. @Autowired
  6. private MailUtils mailUtils;
  7. public List<User> getAll() {
  8. return userMapper.selectAll();
  9. }
  10. @Override
  11. public Integer addUser(User user) {
  12. //将数据存入到数据库
  13. Integer integer = userMapper.addUser(user);
  14. //发送一封激活邮件
  15. 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>");
  16. return integer;
  17. }
  18. @Override
  19. public User findByCode(String code) {
  20. return userMapper.findByCode(code);
  21. }
  22. @Override
  23. public void updateUser(User user) {
  24. userMapper.updateUser(user);
  25. }
  26. }

(9)UserMapper.java 和 UserMapper.xml

  1. @Component
  2. @Mapper
  3. public interface UserMapper {
  4. List<User> selectAll();
  5. Integer addUser(User user);
  6. User findByCode(@Param("code") String code);
  7. void updateUser(User user);
  8. }
  9. <select id="selectAll"
  10. resultType="User">
  11. select *
  12. from
  13. user
  14. </select>
  15. <insert id="addUser" parameterType="com.entities.User"
  16. useGeneratedKeys="true"
  17. keyProperty="id" >
  18. INSERT INTO user (
  19. username,
  20. password,
  21. nickname,
  22. email,
  23. state,
  24. code
  25. )
  26. VALUES
  27. (
  28. #{username},
  29. #{password},
  30. #{nickname},
  31. #{email},
  32. #{state},
  33. #{code}
  34. )
  35. </insert>
  36. <select id="findByCode"
  37. resultType="com.entities.User">
  38. SELECT
  39. *
  40. FROM
  41. user u
  42. WHERE
  43. u. CODE = #{code}
  44. </select>
  45. <update id="updateUser" parameterType="com.entities.User">
  46. UPDATE user
  47. <trim prefix="set" suffixOverrides=",">
  48. <if test="username != null">
  49. username=#{username},
  50. </if>
  51. <if test="password != null">
  52. password=#{password},
  53. </if>
  54. <if test="nickname != null">
  55. nickname=#{nickname},
  56. </if>
  57. <if test="email!=null">
  58. email=#{email},
  59. </if>
  60. state=#{state},
  61. code=#{code}
  62. </trim>
  63. WHERE uid=#{uid}
  64. </update>

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

  1. /*
  2. * 用户激活的 接口
  3. * */
  4. @ResponseBody
  5. @GetMapping("/regist_web/activateServlet")
  6. public Object activateServlet(@RequestParam("code")String code,
  7. HttpServletRequest request,HttpServletResponse response) {
  8. Map<String,Object> map = null;
  9. try {
  10. map = new HashMap<>();
  11. User user = userService.findByCode(code);
  12. if(user != null){
  13. //已经查询到,修改用户的状态
  14. user.setState(1);//已经激活
  15. user.setCode(null);
  16. //激活后修改用户的激活码及状态
  17. userService.updateUser(user);
  18. map.put("state","0");
  19. map.put("message", "您的激活码已激活!请去登录");
  20. }else {
  21. //根据激活码没有查询到该用户
  22. //
  23. map.put("state","0");
  24. map.put("message", "您的激活码有误!请重新激活");
  25. }
  26. }catch (Exception e){
  27. e.printStackTrace();
  28. map.put("state","1");
  29. map.put("message", "發送失敗");
  30. throw new RuntimeException();
  31. }
  32. return map;
  33. }

小结:

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

激活邮件的原理:

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

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

发表评论

表情:
评论列表 (有 0 条评论,127人围观)

还没有评论,来说两句吧...

相关阅读