网站注册(二)
一、准备工作
- 引入commons-lang3依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
用于字符处理
- 配置网站域名
在application.yml
文件中添加以下内容
# 网站域名
community:
path:
domain: http://localhost:8080 #以本机代替
二、编写加密工具类
用于生成随机字符和密码加密
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.DigestUtils;
import java.util.UUID;
public class CommunityUtils {
/**
* 生成随机字符串
*
* @return
*/
public static String generateUUID() {
return UUID.randomUUID().toString().replace("-", "");
}
/**
* md5加密
*
* @param key 待加密字符串
* @return
*/
public static String md5(String key) {
if (StringUtils.isBlank(key)) {
return null;
}
return DigestUtils.md5DigestAsHex(key.getBytes());
}
}
三、提交用户信息
Service层基于Mybatis Plus实现
User.java
类入下
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
import lombok.Data;
/**
*
* @TableName user
*/
@TableName(value ="user")
@Data
public class User implements Serializable {
@TableId(type = IdType.AUTO)
private Integer id;
private String username;
private String password;
private String salt;
private String email;
/**
* 0-普通用户; 1-超级管理员; 2-版主;
*/
private Integer type;
/**
* 0-未激活; 1-已激活;
*/
private Integer status;
private String activationCode;
private String headerUrl;
private Date createTime;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
UserServiceImpl.java
类如下,注册功能由register方法实现,该方法返回各种注册异常信息
主要流程为:
- 用户信息验证
- 密码加密(添加附加信息+md5加密)
- 生成用户激活码
- 完善用户信息用保存
- 发送激活邮件
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nowcoder.community.entity.User;
import com.nowcoder.community.service.UserService;
import com.nowcoder.community.dao.UserMapper;
import com.nowcoder.community.utils.CommunityUtils;
import com.nowcoder.community.utils.MailClient;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/**
*
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
implements UserService{
@Autowired
private MailClient mailClient;
@Autowired
private TemplateEngine templateEngine;
@Value("${community.path.domain}")
private String domain;
@Value("${server.servlet.context-path}")
private String contextPath;
public Map<String, Object> register(User user){
Map<String,Object> map = new HashMap<>();
//空值判断
if (user == null){
throw new IllegalArgumentException("参数不能为空!");
}
if (StringUtils.isBlank(user.getUsername())){
map.put("usernameMsg","账号不能为空!");
return map;
}
if (StringUtils.isBlank(user.getPassword())){
map.put("passwordMsg","密码不能为空!");
return map;
}
if (StringUtils.isBlank(user.getEmail())){
map.put("emailMsg","邮箱不能为空!");
return map;
}
//验证账号是否重复
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
lqw.eq(User::getUsername, user.getUsername());
User u = getOne(lqw);
if (u != null){
map.put("usernameMsg","用户已存在");
}
//验证邮箱是否被注册
lqw.clear();
lqw.eq(User::getEmail, user.getEmail());
u = getOne(lqw);
if (u != null){
map.put("emailMsg","邮箱已存在");
}
//注册用户
//添加随机字符串
user.setSalt(CommunityUtils.generateUUID().substring(0,5));
//密码加密
user.setPassword(CommunityUtils.md5(user.getPassword()+ user.getSalt()));
user.setType(0);
//未激活
user.setStatus(0);
//激活码
user.setActivationCode(CommunityUtils.generateUUID());
user.setHeaderUrl(String.format("https://images.nowcoder.com/head/%dt.png",new Random().nextInt(1000)));
user.setCreateTime(new Date());
//保存
save(user);
//发送激活邮件
Context context = new Context();
context.setVariable("email",user.getEmail());
String url = domain + contextPath + "/activation/" + user.getId() + "/" + user.getActivationCode();
context.setVariable("url",url);
String content = templateEngine.process("/mail/activation",context);
mailClient.sendMail(user.getEmail(),"激活账号",content);
return map;
}
}
激活邮件入下所示:
五、激活账号
处理用户激活链接
- 创建
CommunityConstant
接口,表示不同激活状态
public interface CommunityConstant {
/**
* 激活成功
*/
int ACTIVATION_SUCCESS = 0;
/**
* 重复激活
*/
int ACTIVATION_REPEAT = 1;
/**
* 激活失败
*/
int ACTIVATION_FAILURE = 2;
}
UserServiceImpl
类实现CommunityConstant
接口,并添加activation方法激活账号
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
implements UserService, CommunityConstant {
//...
/**
* 激活账号
*
* @param userId 用户id
* @param code 激活码
* @return
*/
public int activation(int userId, String code) {
//查询user
User user = getById(userId);
if (user.getStatus() == 1) {
//已激活
return ACTIVATION_REPEAT;
} else if (user.getActivationCode().equals(code)) {
//成功激活
LambdaUpdateWrapper<User> luw = new LambdaUpdateWrapper<>();
luw.eq(User::getId, user.getId());
luw.set(User::getStatus, 1);
//更新状态
update(luw);
return ACTIVATION_SUCCESS;
} else {
//激活失败
return ACTIVATION_FAILURE;
}
}
}
- 编写控制层代码
@Controller
public class LoginController implements CommunityConstant {
//...
@GetMapping("/activation/{userId}/{code}")
public String activation(
Model model,
@PathVariable int userId,
@PathVariable String code){
int result = userService.activation(userId, code);
if (result == ACTIVATION_SUCCESS){
model.addAttribute("msg","激活成功,您的账号可以正常使用了。");
model.addAttribute("target","/login");
}else if (result == ACTIVATION_REPEAT){
model.addAttribute("msg","该账号已被激活,无需重复操作。");
model.addAttribute("target","/index");
}else {
model.addAttribute("msg","激活失败,您的账号可以正常使用了。");
model.addAttribute("target","/index");
}
return "/site/operate-result";
}
}
激活成功页面:
