1.本篇文章的代码原理是根据前端传来的用户名到数据库中取对应的邮箱,并通过邮箱帮助类向邮箱发送验证码,将验证码存在session中,最后通过前端传过来的验证码与存在session中的验证码进行比较,如果相同则进行下一步(用户注册时的邮箱验证或者后面面的忘记密码)。

2.调试后台API用的是Swagger

3.用到的依赖:

<!-- javaMail -->
<dependency>
    <groupId>javax.mail</groupId>
    <artifactId>mail</artifactId>
    <version>1.4.6</version>
</dependency>

1.帮助类(即放到utils包下的类) 

1.1EmailConfig

public class EmailConfig {
//发送邮件的方法
    public static void sendEmail(String toEmailAddress, String emailTitle, String emailContent) throws Exception {

        //读取配置文件中的配置信息
        String emailSMTPHost = PropertiesConfig.getEmailKey("emailSMTPHost");
        String emailSMTPPort = PropertiesConfig.getEmailKey("emailSMTPPort");
        String emailAccount = PropertiesConfig.getEmailKey("emailAccount");
        String emailPassword = PropertiesConfig.getEmailKey("emailPassword");


        Properties pros = new Properties();
        //采用debug调试
        pros.setProperty("mail.debug", "true");
        //身份验证
        pros.setProperty("mail.smtp.auth", "true");
        //邮箱端口号,QQ一般为456或者587
        pros.put("mail.smtp.port", emailSMTPPort);
        //设置邮件服务器的主机名,就是那个服务器地址
        pros.setProperty("mail.smtp.host", emailSMTPHost);
        //选择发送邮件的协议
        pros.setProperty("mail.transport.protocol", "smtp");


        //SSL认证,这个主要看邮箱是否基于SSL加密,加密的话需要开启才可以使用
        MailSSLSocketFactory sf = new MailSSLSocketFactory();
        sf.setTrustAllHosts(true);
        //这边需要设置是否使用SSL安全连接
        pros.put("mail.smtp.ssl.enable", "true");
        pros.put("mail.smtp.ssl.socketFactory", sf);

        //创建一个session回话
        Session session = Session.getInstance(pros);

        //获取邮件信息
        Message msg = new MimeMessage(session);

        //设置邮件标题
        msg.setSubject(emailTitle);
        //设置内容
        StringBuilder builder = new StringBuilder();
        //写入内容
        builder.append("\n" + emailContent);
        //设置邮件内容
        //msg.setText(builder.toString());
        msg.setContent(builder.toString(), "text/html;charset=gb2312");

        //设置显示邮件发送时间
        msg.setSentDate(new Date());

        //设置发件人邮箱,这里的InternetAddress有三个参数:发件人邮箱,显示的昵称(需要改成自己的),昵称字符集
        msg.setFrom(new InternetAddress(emailAccount, "发送人的昵称", "utf-8"));
        /现在我们要获取一个邮差了,不然没人传递邮件了
        Transport transport = session.getTransport();
        //连接自己的邮箱
        transport.connect(emailSMTPHost, emailAccount, emailPassword);
        //发送邮件
        transport.sendMessage(msg, new Address[]{new InternetAddress(toEmailAddress)});
        transport.close();

    }
}

1.2 PropertiesConfig

Component
public class PropertiesConfig implements ApplicationListener {
    //保存加载配置参数
    private static Map<String, String> aliPropertiesMap = new HashMap<String, String>();

    //保存邮件配置参数
    private static Map<String, String> emailPropertiesMap = new HashMap<>();

    /*获取配置参数值*/
    public static String getKey(String key) {
        return aliPropertiesMap.get(key);
    }

    /*获取邮件配置参数值*/
    public static String getEmailKey(String key) {
        return emailPropertiesMap.get(key);
    }

    /*监听启动完成,执行配置加载到aliPropertiesMap*/
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof ApplicationReadyEvent) {
            this.init(aliPropertiesMap);//应用启动加载
            this.initEmail(emailPropertiesMap);
        }
    }

    /*初始化加载aliPropertiesMap*/
    public void init(Map<String, String> map) {
        // 获得PathMatchingResourcePatternResolver对象
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        try {
            //加载resource文件(也可以加载resources)
            Resource resources = resolver.getResource("classpath:config/alipay.properties");
            PropertiesFactoryBean config = new PropertiesFactoryBean();
            config.setLocation(resources);
            config.afterPropertiesSet();
            Properties prop = config.getObject();
            //循环遍历所有得键值对并且存入集合
            for (String key : prop.stringPropertyNames()) {
                map.put(key, (String) prop.get(key));
            }
        } catch (Exception e) {
            new Exception("配置文件加载失败");
        }
    }

    /*初始化加载aliPropertiesMap*/
    public void initEmail(Map<String, String> map) {
        // 获得PathMatchingResourcePatternResolver对象
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        try {
            //加载resource文件(也可以加载resources)
            Resource resources = resolver.getResource("classpath:config/email.properties");
            PropertiesFactoryBean config = new PropertiesFactoryBean();
            config.setLocation(resources);
            config.afterPropertiesSet();
            Properties prop = config.getObject();
            //循环遍历所有得键值对并且存入集合
            for (String key : prop.stringPropertyNames()) {
                map.put(key, (String) prop.get(key));
            }
        } catch (Exception e) {
            new Exception("配置文件加载失败");
        }
    }

    /*读取配置文件,将数据放置map内*/
    public static Map<String, Double> getRateMap() {
        Map<String, Double> map = new HashMap<String, Double>();
        // 获得PathMatchingResourcePatternResolver对象
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        try {
            //加载resource文件(也可以加载resources)
            Resource resources = resolver.getResource("classpath:config/payPercent.properties");
            PropertiesFactoryBean config = new PropertiesFactoryBean();
            config.setLocation(resources);
            config.afterPropertiesSet();
            Properties prop = config.getObject();
            //循环遍历所有得键值对并且存入集合
            for (String key : prop.stringPropertyNames()) {
                map.put(key, Double.parseDouble((String) prop.get(key)));
            }
        } catch (Exception e) {
            new Exception("配置文件加载失败");
        }
        return map;
    }
}

2.API接口(根据用户名查询邮箱并发送验证码以及邮箱验证码验证的具体实现) EmailController

@RestController
@RequestMapping("sendEmail")
@Api(basePath = "sendEmail", value = "邮件发送", description = "邮件发送")
public class EmailController {
    @Autowired
    private UserService userService;

    /**
     * 根据用户名查询邮箱并发送验证码
     *
     */
    @RequestMapping(method = RequestMethod.POST, value = "/sendVerifyEmail")
    @SysLog("根据用户名查询邮箱并发送验证码")
    @ApiOperation(value = "根据用户名查询邮箱并发送验证码", notes = "根据用户名查询邮箱并发送验证码", httpMethod = "POST")
    public R sendVerifyEmail(@RequestParam String username, HttpSession session) {
        try {
            //根据用户名查询邮箱
            UserNode frontUser=userService.findUserByUserName(username);
            if(Util.isEmpty(frontUser)){
                return R.error("该用户不存在");
            }else if(Util.isEmpty(frontUser.getEmail())){
                return R.error("未填写邮箱!");
            }else {
                String toEmailAddress = frontUser.getEmail();
                //生成验证码
                String verifyCode = VertifyCodeUtil.generateVertifyCode(6);
                //邮箱标题
                String emailTitle = "【xxx系统】邮箱验证";
                //邮件内容
                String emailContent = "您好,您生成的验证码为:" + verifyCode + ",请在十分钟内完成验证!";
                EmailConfig.sendEmail(toEmailAddress, emailTitle, emailContent);

                //将生成的验证码存入session,用作后续验证
                session.setAttribute("verifyCode", verifyCode);

                session.setAttribute("userId", frontUser.getId());

                return R.ok(toEmailAddress);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return R.error("邮件发送失败");
        }
    }

    /**
     * 邮箱验证码验证
     *
     *
     */
    @RequestMapping(method = RequestMethod.POST, value = "/emailCodeVerify")
    @SysLog("邮箱验证码验证")
    @ApiOperation(value = "邮箱验证码验证", notes = "邮箱验证码验证", httpMethod = "POST")
    public R emailCodeVerify(String verifyCode,HttpSession session) {
        //从session中获取验证码
      //  String code=(String)session.getAttribute("CODE_IN_SESSION");
        String code=(String)session.getAttribute("verifyCode");
        //TimerTask实现10分钟后删除CODE_IN_SESSION
        final Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                //session.removeAttribute("CODE_IN_SESSION");
                session.removeAttribute("verifyCode");
                System.out.println("verifyCode删除成功");
                timer.cancel();
            }
        },10 * 60 * 1000);
        if (verifyCode==null){
            return R.error("验证码不能为空!");
        }
        //十分钟后提示验证码已过期
        if (code==null){
            return R.error("验证码已过期,请重新进行验证!");
        }

        if(Util.isNotEmpty(code)&&Util.isNotEmpty(verifyCode)&&code.equals(verifyCode)){
            //Integer userId=(Integer)session.getAttribute("userId");
          Long userId=(Long)session.getAttribute("userId");
            return R.ok(userId);
        }else{
            return R.error("验证码不正确!");
        }

    }
}