网站注册(二)

一、准备工作

  1. 引入commons-lang3依赖
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.9</version>
</dependency>

用于字符处理

  1. 配置网站域名
    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方法实现,该方法返回各种注册异常信息
主要流程为:

  1. 用户信息验证
  2. 密码加密(添加附加信息+md5加密)
  3. 生成用户激活码
  4. 完善用户信息用保存
  5. 发送激活邮件
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;
    }
}

激活邮件入下所示:

五、激活账号

处理用户激活链接

  1. 创建CommunityConstant接口,表示不同激活状态
public interface CommunityConstant {
    /**
     * 激活成功
     */
    int ACTIVATION_SUCCESS = 0;
    /**
     * 重复激活
     */
    int ACTIVATION_REPEAT = 1;
    /**
     * 激活失败
     */
    int ACTIVATION_FAILURE = 2;
}
  1. 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;
        }
    }
}
  1. 编写控制层代码
@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";
    }
}

激活成功页面:

posted @ 2022-07-19 21:22  DaleLee  阅读(121)  评论(0)    收藏  举报