springboot如何发送邮件,java如何发送邮件随机码作为验证
maven
<dependency><groupId>com.sun.mail</groupId><artifactId>javax.mail</artifactId><version>1.6.2</version></dependency>
然后java
package com.metasoft.common.utils;import java.util.Properties;import javax.mail.Authenticator;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;public final class JavaMailUntil {private JavaMailUntil() {}public static Session createSession() {// 账号信息String username = "skin_2023@qq.com";// 邮箱发送账号String password = "uncinojcclesurcdbb";// 邮箱授权码// 创建一个配置文件,并保存Properties props = new Properties();// SMTP服务器连接信息// 126——smtp.126.com// 163——smtp.163.com// qqsmtp.qq.com"props.put("mail.smtp.host", "smtp.qq.com");// SMTP主机名props.put("mail.smtp.ssl.enable", "true");// 126——25// 163——645props.put("mail.smtp.port", "465");// 主机端口号props.put("mail.smtp.auth", "true");// 是否需要用户认证props.put("mail.smtp.starttls.enale", "true");// 启用TlS加密Session session = Session.getInstance(props,new Authenticator() {@Overrideprotected PasswordAuthentication getPasswordAuthentication() {// TODO Auto-generated method stubreturn new PasswordAuthentication(username,password);}});// 控制台打印调试信息session.setDebug(true);return session;}//正则验证// 验证邮箱地址是否合法public static boolean isValidEmailAddress(String email) {String emailRegex = "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,7}$";return email.matches(emailRegex);}
}
然后就是业务层了,包含发送普通邮件,发送附件,发送图片邮件
/*** 发送邮件*/@PostMapping("/sendEmail")@ApiOperationSupport(order = 18)@ApiOperation(value = "发送激活邮件", notes = "传入id")public R sendEmail(String userIds) throws MessagingException {if (StringUtil.isBlank(userIds)) {return R.fail("请至少选择一个用户");}List<User> userList = userService.list(Wrappers.<User>lambdaQuery().in(User::getId, Func.toLongList(userIds)));// 创建Session会话Session session = JavaMailUntil.createSession();for (User user : userList) {String targetEmail = "";//优先判断user的account是不是邮箱地址,如果不是判断user的email是不是邮箱地址,如果也不是,直接抛出异常// 优先判断user的account是不是邮箱地址if (JavaMailUntil.isValidEmailAddress(user.getAccount())) {targetEmail = user.getAccount();} else {// 如果user的account不是邮箱地址,则判断user的email是不是邮箱地址if (JavaMailUntil.isValidEmailAddress(user.getEmail())) {targetEmail = user.getEmail();} else {// 如果都不是邮箱地址,直接跳过log.info("用户{}的email和account都不是邮箱地址", user.getId());continue;}}MimeMessage message = new MimeMessage(session);message.setSubject("邀请您激活账号");String activationLink = "http://localhost:2888/register?activationCode=" + UUID.randomUUID().toString();String emailContent = "" +"\n" +"感谢您的注册。\n" +"\n" +"您目前处于已完成临时注册的状态。\n" +"\n" +"如需完成注册,请点击以下URL。" + activationLink;//todo 后续改成线上地址message.setText(emailContent);message.setFrom(new InternetAddress("skins_2023@qq.com"));message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(targetEmail));Transport.send(message);}return R.success("操作成功");}/*** 发送邮件带附件*/@GetMapping("/sendEmailForFile")@ApiOperationSupport(order = 18)@ApiOperation(value = "发送邮件带附件", notes = "传入id")public R sendEmailForFile(String userIds) throws MessagingException {try {// 创建会话Session session = JavaMailUntil.createSession();// 创建邮件MimeMessage message = new MimeMessage(session);message.setFrom("发送的邮箱");message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress("主要发送人邮箱"));message.setRecipients(MimeMessage.RecipientType.CC, new InternetAddress[] {new InternetAddress("抄送人邮箱"),new InternetAddress("抄送人邮箱")});message.setSubject("主题");// 邮件主体BodyPart textPart = new MimeBodyPart();textPart.setContent("文件内容","text/html;charset=utf-8");// 邮件附件BodyPart filePart = new MimeBodyPart();filePart.setFileName("附件显示名字.类型名");// 提交附件文件filePart.setDataHandler(new DataHandler(new ByteArrayDataSource(Files.readAllBytes(Paths.get("本地文件路径")),"application/octet-stream")));Multipart multipart = new MimeMultipart();multipart.addBodyPart(textPart);multipart.addBodyPart(filePart);// 将邮件装入信封message.setContent(multipart);Transport.send(message);} catch (AddressException e) {e.printStackTrace();} catch (MessagingException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return R.success("操作成功");}/*** 发送邮件带图片*/@GetMapping("/sendEmailForPhoto")@ApiOperationSupport(order = 18)@ApiOperation(value = "发送邮件带图片", notes = "传入id")public R sendEmailForPhoto(String userIds) throws MessagingException {try {// 创建会话Session session = JavaMailUntil.createSession();// 创建邮件MimeMessage message = new MimeMessage(session);message.setFrom("发送的邮箱");message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress("主要发送人邮箱"));message.setRecipients(MimeMessage.RecipientType.CC, new InternetAddress[] {new InternetAddress("抄送人邮箱"),new InternetAddress("抄送人邮箱")});message.setSubject("主题");// 邮件主体BodyPart textPart = new MimeBodyPart();StringBuilder stringBuilder = new StringBuilder();stringBuilder.append("文字");stringBuilder.append("文字");stringBuilder.append("<img src=\"cid:自定义id\"/>");textPart.setContent(stringBuilder.toString(),"text/html;charset=utf-8");// 邮件附件BodyPart filePart = new MimeBodyPart();filePart.setFileName("图片名称.jpg");// 提交附件文件filePart.setDataHandler(new DataHandler(new ByteArrayDataSource(Files.readAllBytes(Paths.get("本地路径")),"application/octet-stream")));filePart.setHeader("Content-ID","自定义id");Multipart multipart = new MimeMultipart();multipart.addBodyPart(textPart);multipart.addBodyPart(filePart);// 将邮件装入信封message.setContent(multipart);Transport.send(message);} catch (AddressException e) {e.printStackTrace();} catch (MessagingException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return R.success("操作成功");}/*** 生成六位数随机验证码*/public String generateRandomCode() {Random random = new Random();int code = 100000 + random.nextInt(900000);return String.valueOf(code);}/*** 发送包含验证码的邮件*/@GetMapping("/sendVerificationCode")public R sendVerificationCode(@RequestParam("emailAddress") String emailAddress) throws MessagingException {//验证邮箱地址是否正确boolean isValid = JavaMailUntil.isValidEmailAddress(emailAddress);if (!isValid) {return R.fail("邮箱地址不正确");}String verificationCode = generateRandomCode();// 创建邮件内容String emailContent = "您的验证码是:" + verificationCode+"。请在注册或登录时使用。有效期为10分钟。";// 创建Session会话Session session = JavaMailUntil.createSession();// 创建邮件对象MimeMessage message = new MimeMessage(session);message.setSubject("密码重置验证码");message.setText(emailContent);message.setFrom(new InternetAddress("skins_2023@qq.com"));message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(emailAddress));// 发送Transport.send(message);//验证码存入redis中方便后续读取,有效期为十分钟bladeRedis.getRedisTemplate().opsForValue().set("verificationCode:" + emailAddress, verificationCode, 10, TimeUnit.MINUTES);return R.success("验证码已发送到您的邮箱,请查收!");}/*** 账号激活*/@PostMapping("/activateAccount")public R activateAccount(@RequestBody RegisterUserVO userVO) throws MessagingException {log.info(userVO.toString());return R.success("账号激活");}/*** 忘记密码-修改密码*/@PostMapping("/changePassword")public R changePassword(@RequestBody RegisterUserVO userVO) throws MessagingException {log.info(userVO.toString());//查询是否存在此邮箱的账号User user = userService.getOne(new QueryWrapper<User>().lambda().eq(User::getAccount, userVO.getUsername()));//如果查询不到用户,则返回错误信息if (user == null) {return R.fail("用户不存在");}//判断两次输入的密码是否一致if (!userVO.getPassword().equals(userVO.getPassword2())) {return R.fail("两次输入的密码不一致");}//判断验证码是否正确String verificationCode = (String)bladeRedis.getRedisTemplate().opsForValue().get("verificationCode:" + userVO.getUsername());if (!verificationCode.equals(userVO.getEmailCode())) {return R.fail("邮箱验证码错误");}// 修改密码userService.update(Wrappers.<User>update().lambda().set(User::getPassword, DigestUtil.hex(userVO.getPassword())).eq(User::getId, user.getId()));return R.success("密码修改成功");}}
顺便也发出我写的前端代码,vue
<template><div class="register-container" ref="register"><p style="line-height:150%; margin:50pt 0pt 20pt 50pt; text-align:center;"><span style="font-family:FZXiaoBiaoSong-B05S; font-size:26pt; display:inline-block;">重置密码</span></p><div class="register-form"><el-form :model="form" ref="form" :rules="rules" label-width="100px"><el-form-item label="登录邮箱" prop="username"><el-input v-model="form.username" placeholder="请输入邮箱"></el-input></el-form-item><el-form-item label="邮箱验证码" prop="emailCode"><el-input v-model="form.emailCode" placeholder="请输入邮箱验证码"></el-input><el-button type="primary" @click="sendEmailCode" :disabled="countDown > 0">{{ countDown > 0 ? countDown + '秒后重新发送' : '发送验证码' }}</el-button></el-form-item><el-form-item label="新密码" prop="password"><el-input type="password" v-model="form.password" placeholder="请输入新密码"></el-input></el-form-item><el-form-item label="确认新密码" prop="password2"><el-input type="password" v-model="form.password2" placeholder="请再次输入新密码"></el-input></el-form-item><el-form-item><el-button type="primary" @click="submitForm">提交</el-button></el-form-item></el-form></div></div>
</template><script>
import {changePassword, sendVerificationCode} from "@/api/register/register";
import md5 from 'js-md5';export default {data() {return {form: {username: '',emailCode: '',password: '',password2: '',},rules: {username: [{ required: true, message: '请输入邮箱', trigger: 'blur' },],emailCode: [{ required: true, message: '请输入邮箱验证码', trigger: 'blur' },],password: [{ required: true, message: '请输入密码', trigger: 'blur' },],password2: [{ required: true, message: '请再次输入密码', trigger: 'blur' },],},countDown: 0,};},methods: {sendEmailCode() {// 编写发送邮箱验证码的逻辑if (this.countDown === 0) {// 模拟发送验证码,实际开发中调用后端接口console.log('发送验证码');sendVerificationCode(this.form.username).then(res => {//如果res的状态码为200,表示发送成功if (res.status === 200) {this.$message.success('验证码发送成功');} else {this.$message.error('验证码发送失败');}});this.countDown = 60;const timer = setInterval(() => {if (this.countDown > 0) {this.countDown--;} else {clearInterval(timer);}}, 1000);}},submitForm() {console.log("要发送的信息====", this.form);//todo 后续对密码的安全性做处理this.form.password = md5(this.form.password);this.form.password2 = md5(this.form.password2);changePassword(this.form).then(res => {this.$message({ type: "success", message: "提交成功!" });this.resetForm();}, error => {this.$message({ type: "error", message: "提交失败,请重试!" });});},resetForm() {this.form = {username: '',emailCode: '',password: '',password2: '',};},},
};
</script><style scoped>
.register-container {text-align: center;
}.register-form {width: 400px;margin: 0 auto;
}.el-button {margin-left: 10px;
}.el-form-item__content {display: flex;
}.el-input {flex: 1;
}
</style>
这个就是重置密码 利用邮箱验证60秒的功能