需要的依赖
<!-- 发送邮件所需要的jar包-->
<!--javaMail-->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
<version>1.5.6</version>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.5.3</version>
</dependency>
mapper层
package cn.tedu.kawasaki.mapper;
import cn.tedu.kawasaki.pojo.entity.User;
import cn.tedu.kawasaki.pojo.vo.UserVO;
import org.springframework.stereotype.Repository;
/**
* 处理用户数据的Mapper接口
*
* @author Edgar
* @version 0.0.1
*/
@Repository
public interface UserMapper {
/**
* 根据用户名查询用户信息
*
* @param email 邮箱
* @return
*/
UserVO selectByEmail(String email);
/**
* 添加用户
*
* @param user
* @return
*/
int insert(User user);
/**
* 更新
*
* @param user 用户
* @return int
*/
int update(User user);
}
service层
1、service接口
package cn.tedu.kawasaki.service;
import org.springframework.transaction.annotation.Transactional;
//声明式事务
@Transactional
public interface UserService {
/**
* 通过电子邮件注册
*
* @param email 电子邮件
* @param pwd 密码
*/
void registerByEmail(String email, String pwd);
/**
* 确认电子邮件
*
* @param email 电子邮件
* @param code 验证码
*/
void confirmEmail(String email, String code);
}
2、service实现类
package cn.tedu.kawasaki.service.impl;
import cn.tedu.kawasaki.ex.ServiceException;
import cn.tedu.kawasaki.mapper.UserMapper;
import cn.tedu.kawasaki.pojo.entity.User;
import cn.tedu.kawasaki.pojo.vo.UserVO;
import cn.tedu.kawasaki.service.UserService;
import cn.tedu.kawasaki.utils.EmailUtil;
import cn.tedu.kawasaki.utils.FormatUtil;
import cn.tedu.kawasaki.web.ServiceCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Random;
/**
* 处理用户业务的实现类
*
*/
@Slf4j
@Service
public class UserServiceImpl implements UserService {
@Autowired
UserMapper userMapper;
@Autowired
HttpServletRequest request;
/**
* 通过用户的E-mail注册用户
*
* @param email
* @param pwd
* @return
*/
@Override
public void registerByEmail(String email, String pwd) {
// 校验邮箱是否合法
if (!FormatUtil.isEmail(email)) {
// 不合法则直接抛出异常
String message = "注册用户失败,请稍后再试";
throw new ServiceException(ServiceCode.ERR_BAD_REQUEST,message);
}
//验证邮箱是否注册过
UserVO userVO = userMapper.selectByEmail(email);
if (userVO==null){
//先将一个未激活的用户插入到数据库中
User user = User.builder()
.email(email)
.password(pwd)
.state(0)
.build();
int rows = userMapper.insert(user);
if (rows!=1){
String message = "注册用户失败,请稍后再试";
throw new ServiceException(ServiceCode.ERR_INSERT,message);
}
//邮箱合法则发送校验邮件以便于激活用户
judgeMail(email);
}
judgeMail(email);
}
@Override
public void confirmEmail(String email, String code) {
HttpSession session = request.getSession();
String codeInSession = (String) session.getAttribute("code");
if (code.equals(codeInSession)) {
UserVO userVO = userMapper.selectByEmail(email);
if (userVO==null){
String message = "注册用户失败,请稍后再试";
throw new ServiceException(ServiceCode.ERR_SELECT,message);
}
if (userVO.getState()==1){
String message = "注册用户失败,该用户已经注册";
throw new ServiceException(ServiceCode.ERR_SELECT,message);
}
// 激活这个用户
userVO.setState(1);
User user = User.builder()
.id(userVO.getId())
.state(userVO.getState())
.build();
int rows = userMapper.update(user);
if (rows!=1){
String message = "注册用户失败,请稍后再试";
throw new ServiceException(ServiceCode.ERR_UPDATE,message);
}
return;
}
String message = "注册用户失败,验证码错误";
throw new ServiceException(ServiceCode.ERR_BAD_REQUEST,message);
}
/**
* 发送给他一个校验码。
*
* @param email
*/
private void judgeMail(String email) {
HttpSession session = request.getSession();
//生成随机验证码
Random random = new Random();
StringBuilder code = new StringBuilder();
for (int i = 0; i < 6; i++) {
code.append(random.nextInt(10));
}
String massage = "您的邮箱是"+ email+",您的验证码是:" +code.toString()+"如果不知道,请无视。" ;
log.debug("校验码:{}",code);
//下面有EmailUtil代码
EmailUtil.sendMail(email, massage);
session.setAttribute("code", code.toString());
}
}
controller层
package cn.tedu.kawasaki.controller;
import cn.tedu.kawasaki.service.UserService;
import cn.tedu.kawasaki.web.JsonResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* 处理用户相关请求控制器
*
* @author Edgar
* @version 1.0.0
*/
@Slf4j
@Api(tags = "01. 用户管理模块")
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
UserService userService;
/**
* 邮件注册
*
* @return
*/
@ApiOperation("邮箱注册")
@ApiImplicitParams({
@ApiImplicitParam(value = "email", name = "email", example = "edgar1223@163.com"),
@ApiImplicitParam(value = "pwd", name = "pwd", example = "123456")
}
)
@PostMapping("/registerByEmail")
public JsonResult registerByEmail(@RequestParam(value = "email", required = true) String email,
@RequestParam(value = "pwd", required = true) String pwd
) {
userService.registerByEmail(email, pwd);
return JsonResult.ok();
}
/**
* 校验邮箱
*/
@ApiOperation("校验邮箱")
@ApiImplicitParams({
@ApiImplicitParam(value = "email", name = "email", example = "edgar1223@163.com"),
@ApiImplicitParam(value = "code", name = "code", example = "123456")
}
)
@GetMapping(value = "/confirmEmail")
public JsonResult confirmEmail(@RequestParam(value = "email", required = true) String email,
@RequestParam(value = "code", required = true) String code) {
userService.confirmEmail(email, code);
return JsonResult.ok();
}
}
EmailUtil类
package cn.tedu.kawasaki.utils;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.util.Date;
import java.util.Properties;
/**
* 电子邮件工具类
*
* @author Edgar
* @version 1.0.0
* @date 2022/12/23
*/
public class EmailUtil {
/**
* 发送邮箱:XXX@163.com
*/
private static final String MY_EMAIL_ACCOUNT = "edgar1223@163.com";
/**
* 授权码:ECCTKZAVPRIQGBBE
*/
private static final String MY_EMAIL_PASSWORD = "WEVJEYBEJHBKREML";// 密码,是你自己的设置的授权码
// SMTP服务器(这里用的163 SMTP服务器)
/**
* 163代理服务器:smtp.163.com
*/
private static final String MEAIL_163_SMTP_HOST = "smtp.163.com";
/**
* 163 使用的端口:25
*/
private static final String SMTP_163_PORT = "25";// 端口号,这个是163使用到的;QQ的应该是465或者875
/**
* @param targetAddr 目标邮箱地址
* @param code 验证码
*/
public static void sendMail(String targetAddr, String code) {
Properties p = new Properties();
p.setProperty("mail.smtp.host", MEAIL_163_SMTP_HOST);
p.setProperty("mail.smtp.port", SMTP_163_PORT);
p.setProperty("mail.smtp.socketFactory.port", SMTP_163_PORT);
p.setProperty("mail.smtp.auth", "true");
p.setProperty("mail.smtp.socketFactory.class", "SSL_FACTORY");
Session session = Session.getInstance(p, new Authenticator() {
// 设置认证账户信息
@Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(MY_EMAIL_ACCOUNT, MY_EMAIL_PASSWORD);
}
});
// session.setDebug(true);
MimeMessage message = new MimeMessage(session);
try {
// 发件人
message.setFrom(new InternetAddress(MY_EMAIL_ACCOUNT));
// 收件人和抄送人
message.setRecipients(Message.RecipientType.TO, targetAddr);
// 内容(这个内容还不能乱写,有可能会被SMTP拒绝掉;多试几次吧)
message.setSubject("注册验证码");
message.setContent("您的验证码为 : <h1>" + code+"</h1>", "text/html;charset=UTF-8");
message.setSentDate(new Date());
message.saveChanges();
Transport.send(message);
} catch (MessagingException e) {
e.printStackTrace();
}
}
}
FormatUtil格式类
package cn.tedu.kawasaki.utils;
import java.util.regex.Pattern;
public class FormatUtil {
/**
* 正则表达式:验证用户名
*/
private static final String REGEX_USERNAME = "^[a-zA-Z]\\w{5,20}$";
/**
* 正则表达式:验证密码
*/
private static final String REGEX_PASSWORD = "^[a-zA-Z0-9]{6,20}$";
/**
* 正则表达式:验证手机号
*/
private static final String REGEX_MOBILE = "^((17[0-9])|(14[0-9])|(13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
/**
* 正则表达式:验证邮箱
*/
private static final String REGEX_EMAIL = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
/**
* 正则表达式:验证汉字
*/
private static final String REGEX_CHINESE = "^[\u4e00-\u9fa5],{0,}$";
/**
* 正则表达式:验证身份证
*/
private static final String REGEX_ID_CARD = "(^\\d{18}$)|(^\\d{15}$)";
/**
* 正则表达式:验证URL
*/
private static final String REGEX_URL = "http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&=]*)?";
/**
* 正则表达式:验证IP地址
*/
private static final String REGEX_IP_ADDR = "(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)";
/**
* 校验用户名
*
* @param username
* @return 校验通过返回true,否则返回false
*/
public static boolean isUsername(String username) {
return Pattern.matches(REGEX_USERNAME, username);
}
/**
* 校验密码
*
* @param password
* @return 校验通过返回true,否则返回false
*/
public static boolean isPassword(String password) {
return Pattern.matches(REGEX_PASSWORD, password);
}
/**
* 校验手机号
*
* @param mobile
* @return 校验通过返回true,否则返回false
*/
public static boolean isMobile(String mobile) {
return Pattern.matches(REGEX_MOBILE, mobile);
}
/**
* 校验邮箱
*
* @param email
* @return 校验通过返回true,否则返回false
*/
public static boolean isEmail(String email) {
return Pattern.matches(REGEX_EMAIL, email);
}
/**
* 校验汉字
*
* @param chinese
* @return 校验通过返回true,否则返回false
*/
public static boolean isChinese(String chinese) {
return Pattern.matches(REGEX_CHINESE, chinese);
}
/**
* 校验身份证
*
* @param idCard
* @return 校验通过返回true,否则返回false
*/
public static boolean isIDCard(String idCard) {
return Pattern.matches(REGEX_ID_CARD, idCard);
}
/**
* 校验URL
*
* @param url
* @return 校验通过返回true,否则返回false
*/
public static boolean isUrl(String url) {
return Pattern.matches(REGEX_URL, url);
}
/**
* 校验IP地址
*
* @param ipAddr
* @return
*/
public static boolean isIPAddr(String ipAddr) {
return Pattern.matches(REGEX_IP_ADDR, ipAddr);
}
}