用户注册时要发送验证码到邮箱,以此验证邮箱是否有效。因此该服务分为两部分,首先是发送邮箱验证码,并放入Redis缓存 ,其次是新增邮箱账户信息。
邮箱验证码 接口信息 使用字节流 的方式写回前端
定义Mapper 将验证码置为无效
EmailCodeMapper public interface EmailCodeMapper extends BaseMapper <EmailCode> { void disableEmailCode (@Param("email") String email) ; }
在 EmailCodeMapper.xml 中实现接口,使用乐观锁
EmailCodeMapper.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace ="com.swx.easypan.mapper.EmailCodeMapper" > <select id ="disableEmailCode" > update email_code set status = 1 where email = #{email} and status = 0 </select > </mapper >
定义Service 找到 EmailCodeService,定义发送验证码方法:
public interface EmailCodeService extends IService <EmailCode> { void sendEmailCode (String email, Integer type) ; }
在 EmailCodeServiceImpl 实现该方法,发送的同时将验证码写入数据库
EmailCodeServiceImpl @Service public class EmailCodeServiceImpl extends ServiceImpl <EmailCodeMapper, EmailCode> implements EmailCodeService { private final JavaMailSender javaMailSender; private final RedisComponent redisComponent; @Resource private AppConfig appConfig; public EmailCodeServiceImpl (JavaMailSender javaMailSender, RedisComponent redisComponent) { this .javaMailSender = javaMailSender; this .redisComponent = redisComponent; } @Override @Transactional(rollbackFor = Exception.class) public void sendEmailCode (String email, Integer type) { String code = StringTools.getRandomNumber(Constants.LENGTH_5); sendMailCode(email, code); baseMapper.disableEmailCode(email); EmailCode emailCode = new EmailCode (); emailCode.setCode(code); emailCode.setEmail(email); emailCode.setStatus(Constants.ZERO); this .save(emailCode); } private void sendMailCode (String toEmail, String code) { try { MimeMessage message = javaMailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper (message, true ); helper.setFrom(appConfig.getSendUsername()); helper.setTo(toEmail); SysSettingsDTO sysSettingsDto = redisComponent.getSysSettingDto(); helper.setSubject(sysSettingsDto.getRegisterMailTitle()); helper.setText(String.format(sysSettingsDto.getRegisterEmailContent(), code)); helper.setSentDate(new Date ()); javaMailSender.send(message); } catch (Exception e) { throw new BizException ("邮件发送失败" ); } } }
定义Controller 在 UserInfoController 下定义接口
UserInfoController @RestController("userInfoController") @ResponseResult @Validated public class UserInfoController { private final UserInfoService userInfoService; private final EmailCodeService emailCodeService; @Resource AppConfig appConfig; public UserInfoController (UserInfoService userInfoService, EmailCodeService emailCodeService) { this .userInfoService = userInfoService; this .emailCodeService = emailCodeService; } @PostMapping("/sendEmailCode") public void sendEmailCode (HttpSession session, @NotNull String email, @NotNull String checkCode, @NotNull Integer type) { try { if (!checkCode.equalsIgnoreCase((String) session.getAttribute(Constants.CHECK_CODE_KEY_EMAIL))) { throw new BizException ("图片验证码错误" ); } if (type == 0 ) { UserInfo userInfo = userInfoService.getOne(new LambdaQueryWrapper <UserInfo>().eq(UserInfo::getEmail, email)); if (null != userInfo) { throw new BizException ("邮箱已存在" ); } } emailCodeService.sendEmailCode(email, type); } finally { session.removeAttribute(Constants.CHECK_CODE_KEY_EMAIL); } } }
用户注册服务 接口信息
图片验证码DTO 在包com.swx.easypan.entity.dto,下创建 RegisterDTO 实体类,将下面代码放入:
@Data public class RegisterDTO { @Email private String email; @NotNull private String nickname; @NotNull @Size(min = 8, max = 18, message = "密码长度在8-18之间") private String password; @NotNull private String checkCode; @NotNull private String emailCode; }
定义Mapper 将验证码置为无效
EmailCodeMapper public interface EmailCodeMapper extends BaseMapper <EmailCode> { void disableEmailCode (@Param("email") String email) ; }
在 EmailCodeMapper.xml 中实现接口,使用乐观锁
EmailCodeMapper.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace ="com.swx.easypan.mapper.EmailCodeMapper" > <select id ="disableEmailCode" > update email_code set status = 1 where email = #{email} and status = 0 </select > </mapper >
定义Service 找到 UserInfoService接口,在其中添加:
UserInfoService void register (RegisterDTO registerDto) ;
在 UserInfoServiceImpl 中实现该方法,首先校验用户是否已经注册,然后校验其邮箱验证码,没有问题,则创建新用户,并初始化基础信息。
UserInfoServiceImpl @Service public class UserInfoServiceImpl extends ServiceImpl <UserInfoMapper, UserInfo> implements UserInfoService { private final EmailCodeService emailCodeService; private final RedisComponent redisComponent; @Resource private AppConfig appConfig; public UserInfoServiceImpl (EmailCodeService emailCodeService, RedisComponent redisComponent) { this .emailCodeService = emailCodeService; this .redisComponent = redisComponent; } @Override @Transactional(rollbackFor = Exception.class) public void register (RegisterDTO registerDto) { UserInfo emailUser = this .getOne(new LambdaQueryWrapper <UserInfo>().eq(UserInfo::getEmail, registerDto.getEmail())); if (null != emailUser) { throw new BizException ("邮箱账号已经存在" ); } UserInfo nickNameUser = this .getOne(new LambdaQueryWrapper <UserInfo>().eq(UserInfo::getNickname, registerDto.getNickname())); if (null != nickNameUser) { throw new BizException ("邮箱昵称已经存在" ); } emailCodeService.checkCode(registerDto.getEmail(), registerDto.getEmailCode()); String userId = StringTools.getRandomNumber(Constants.LENGTH_10); UserInfo userInfo = new UserInfo (); userInfo.setId(userId); userInfo.setNickname(registerDto.getNickname()); userInfo.setEmail(registerDto.getEmail()); userInfo.setPassword(MD5.encrypt(registerDto.getPassword())); userInfo.setUseSpace(0L ); SysSettingsDTO sysSettingDto = redisComponent.getSysSettingDto(); userInfo.setTotalSpace(sysSettingDto.getUserInitSpace() * Constants.MB); this .save(userInfo); } }
定义Controller 在 UserInfoController 下定义接口
UserInfoController @RestController("userInfoController") @ResponseResult @Validated public class UserInfoController { private final UserInfoService userInfoService; public UserInfoController (UserInfoService userInfoService) { this .userInfoService = userInfoService; } @PostMapping("/register") public void register (HttpSession session, @Valid @RequestBody RegisterDTO registerDto) { try { if (!registerDto.getCheckCode().equalsIgnoreCase((String) session.getAttribute(Constants.CHECK_CODE_KEY))) { throw new BizException ("图片验证码错误" ); } userInfoService.register(registerDto); } finally { session.removeAttribute(Constants.CHECK_CODE_KEY); } } }