邮件发送
温馨提示:这篇文章已超过625天没有更新,请注意相关的内容是否还可用!
发送邮件的过程
(图片来源网络,侵删)
(图片来源网络,侵删)
1、添加依赖,说明:添加完依赖以后记得刷新dependency,防止没有及时更新
!--发送邮件-->
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-mailartifactId>
dependency>
2、在application.xml中配置邮件信息(和application同级)
说明:对应的邮件服务器如网易邮箱要开启POP3 / SMTP服务
mail:
host: smtp.163.com
username: merlinssea@163.com
password: PIJCHLGOSQAPDVFN
from: merlinssea@163.com
properties.mail.smtp.starttls.enable: true
properties.mail.smtp.starttls.required: true
properties.mail.smtp.ssl.enable: true
default-encoding: utf-8
3、编写业务类MailServicceImpl
public class MailServiceImpl implements MailService {
/**
* springboot 提供的一个发送邮件的简单抽象,直接注入即可
*/
private JavaMailSender mailSender;
/**
* 从application.yml中读取 merlinssea@163.com
*/
"${spring.mail.from}") (
private String from;
/**
* 发送邮件
* @param to 收件人
* @param subject 主题
* @param content 内容
*/
public void sendMail(String to, String subject, String content) {
//创建一个邮箱消息对象
SimpleMailMessage message = new SimpleMailMessage();
//配置邮箱发送人
message.setFrom(from);
//邮件的收件人
message.setTo(to);
//邮件的主题
message.setSubject(subject);
//邮件的内容
message.setText(content);
mailSender.send(message);
log.info("邮件发送成功:{}",message.toString());
}
}
4、编写NotifyServiceImpl类,只负责发送邮件验证码服务器 发邮件服务器 发邮件,如果上一次发送的验证码在60s内,那么就是重复发送,拒绝本次发送。方法:value拼接时间戳
public class NotifyServiceImpl implements NotifyService {
private MailService mailService;
private RedisTemplate redisTemplate;
/**
* 验证码的标题
*/
private static final String SUBJECT= "lianglin 验证码";
/**
* 验证码的内容
*/
private static final String CONTENT= "您的验证码是%s,有效时间是60秒";
/**
* 如果用户重复发送验证码,那么先判别之前60s没是否发送过验证码,发送过则拒绝发送,否则发送
* 方法:在把验证码存入redis之前拼接时间戳 即:code_时间戳
* @param sendCodeEnum
* @param to
* @return
*/
public JsonData sendCode(SendCodeEnum sendCodeEnum, String to) {
String cacheKey = String.format(CacheKey.CHECK_CODE_KEY,sendCodeEnum.name(),to);
String cacheValue = (String) redisTemplate.opsForValue().get(cacheKey);
//如果不为空,则判断是否60秒内重复发送
if(StringUtils.isNotBlank(cacheValue)){
long ttl = Long.parseLong(cacheValue.split("_")[1]);
//当前时间戳-验证码发送时间戳,如果小于60秒,则不给重复发送
if(CommonUtil.getCurrentTimestamp() - ttl < 1000*60){
log.info("重复发送验证码,时间间隔:{} 秒",(CommonUtil.getCurrentTimestamp()-ttl)/1000);
return JsonData.buildResult(BizCodeEnum.CODE_LIMITED);
}
}
String code = CommonUtil.getRandomCode(6);
//通过对value拼接时间戳的f方法,可以避免在小范围时间内重复发送
String value = code+"_"+CommonUtil.getCurrentTimestamp();
if(CheckUtil.isEmail(to)){
/**
* 这里的code是自己生成的,和之前的图形验证码无关,只有图形验证码通过了,才会调用这个验证码
*/
//后续这个code验证码还得存redis中
mailService.sendMail(to,SUBJECT, String.format(CONTENT, value));
return JsonData.buildSuccess();
}else if(CheckUtil.isPhone(to)){
//手机号发送手机验证码
//TODO
}
return JsonData.buildResult(BizCodeEnum.CODE_TO_ERROR);
}
}
3、编写NotifyController对外api接口[通过第一步可以提高被薅羊毛的成本]
1、先匹配用户发来的图形验证码和redis中存的图形验证码是否一致
2、再调用发送邮件验证码服务
/**
* 发送邮箱验证码
* 1、首先匹配图形验证码是否正常
* 2、再发送邮箱验证码
*
* @param to 接收方邮箱
* @param captcha 接收方输入的图形验证码
* @param request
* @return
*/
public JsonData sendRegisterCode( String to,
String captcha,
HttpServletRequest request) {
String cacheKey = getCaptchaKey(request);//根据用户的request获取缓存key
String cacheCaptcha = redisTemplate.opsForValue().get(cacheKey);
if (captcha != null && cacheCaptcha != null && captcha.equalsIgnoreCase(cacheCaptcha)) {
//图形验证码通过,发送邮件
redisTemplate.delete(cacheKey);
JsonData jsonData = notifyService.sendCode(SendCodeEnum.USER_REGISTER, to);
return jsonData;
} else {
//图形验证码没通过
return JsonData.buildResult(BizCodeEnum.CODE_CAPTCHA_ERROR);
}
}
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。