一、邮箱开启SMTP服务

以qq邮箱为例

进入邮箱设置页面后选择账户

image-20220416165730262

移动至下方的POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务image-20220416165842585

选择开启IMAP/SMTP服务,并获得授权码

二、导入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>

三、配置邮箱服务参数

如果没有在配置文件中配置该参数,在注入JavaMailSender的bean时会出现无法找到bean的错误

# smtp服务器
spring.mail.host=smtp.qq.com
# smtp用户名
spring.mail.username=1294967895@qq.com
# 服务授权码
spring.mail.password=ltlbekkgmkgtbabb

四、编写邮件发送类

package cn.ken.blog.common.utils;

import cn.ken.blog.common.exception.BusinessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

/**
 * @author Ken-Chy129
 * @date 2022/4/16 16:40
 */
@Component
public class EmailUtils {
    
    @Autowired
    private JavaMailSender javaMailSender;
    
    @Value("${spring.mail.username}")
    private String from;
    
    public void sendEmail(String to, String subject, String context) {
        try {
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
            mimeMessageHelper.setFrom(from);
            mimeMessageHelper.setTo(to);
            mimeMessageHelper.setSubject(subject);
            mimeMessageHelper.setText(context, true);
            javaMailSender.send(mimeMessage);
        } catch (BusinessException e) {
            throw new BusinessException(e.getErrorMessage());
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }
}

五、测试发送邮件

package cn.ken.blog.service.impl;

import cn.ken.blog.common.domain.Result;
import cn.ken.blog.common.enums.ErrorCodeEnum;
import cn.ken.blog.common.enums.StatusEnum;
import cn.ken.blog.common.exception.BusinessException;
import cn.ken.blog.common.utils.EmailUtils;
import cn.ken.blog.entity.User;
import cn.ken.blog.mapper.UserMapper;
import cn.ken.blog.service.IUserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Random;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Ken-Chy129
 * @since 2022-04-15
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private HttpServletRequest request;
    
    @Autowired
    private EmailUtils emailUtils;

    @Override
    public Result<String> sendOutEmail(String email) throws BusinessException {
        if (this.selectByEmail(email)) {
            return new Result<String>().error(ErrorCodeEnum.USER_EMAIL_EXISTS);
        }
        String subject = "标题:请收好您的验证码";
        String code = String.valueOf(new Random().nextInt(899999) + 100000);
        request.getSession().setAttribute("code", code);
        String msg = "<h4>欢迎您在Ken-Chy129的博客注册</h4>"+"<p style='color:#F00'>您的验证码为:"+code+"</p>";
        emailUtils.sendEmail(email, subject, msg);
        return new Result<String>().success("发送邮件成功!");
    }

    @Override
    public boolean selectByEmail(String email) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(User::getEmail,email)
                             .eq(User::getStatus, StatusEnum.NORMAL.getStatus());
        return userMapper.selectOne(queryWrapper) != null;
    }
}

进入swagger测试接口,输入要发送的邮箱,点击executeimage-20220416172902766

发送成功

image-20220416173007189

六、常见问题:JavaMailSend为null

问题原因:没有将写的类注入

必须要用@Component将自己写的类先用springboot容器管理

@Component
public class EmailUtils {
    @Autowired
    private JavaMailSender javaMailSender;

    @Value("${spring.mail.username}")
    private String from;

    public void sendEmail(String to, String subject, String context) {
        try {
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
            mimeMessageHelper.setFrom(from);
            mimeMessageHelper.setTo(to);
            mimeMessageHelper.setSubject(subject);
            mimeMessageHelper.setText(context, true);
            javaMailSender.send(mimeMessage);
        } catch (BusinessException e) {
            throw new BusinessException(e.getErrorMessage());
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }
}

之后使用时通过注入EmailUtils整个类再调用其中的方法,不能通过new使用

Q.E.D.


   七岁几胆敢预言自己,操一艘战机