1.注册功能

开发功能模块可以分步开发,先分析需求,再根据实际需求做出具体实现

1.访问注册页面

点击顶部链接打开注册页面

controller

@RequestMapping(value = "/register", method = RequestMethod.POST)
    public String register(Model model, User user) {
        Map<String, Object> map = userService.register(user);
        if (map == null || map.isEmpty()) {
            model.addAttribute("msg", "注册成功,请前往邮箱激活");
            model.addAttribute("target", "/index");
            return "/site/operate-result";
        } else {
            model.addAttribute("usernameMsg", map.get("usernameMsg"));
            model.addAttribute("passwordMsg", map.get("passwordMsg"));
            model.addAttribute("emailMsg", map.get("emailMsg"));
            return "site/register";
        }

    }

并新增Util工具类

public class CommunityUtil {

    //生成随机字符串
    public static String generateUUID() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

    //MD5加密
    //password + salt ->加密
    public static String md5(String key) {
        if (StringUtils.isBlank(key)) {
            return null;
        }
        return DigestUtils.md5DigestAsHex(key.getBytes());
    }

    public static String getJSONString(int code, String msg, Map<String, Object> map) {
        JSONObject json = new JSONObject();
        json.put("code", code);
        json.put("msg", msg);
        if (map != null) {
            for (String key : map.keySet()) {
                json.put(key, map.get(key));
            }
        }
        return json.toJSONString();
    }

    public static String getJSONString(int code, String msg) {
        return getJSONString(code, msg, null);
    }

    public static String getJSONString(int code, Map<String, Object> map) {
        return getJSONString(code, null, map);
    }

    public static String getJSONString(int code){
        return getJSONString(code,null,null);
    }

}

UserService中的register方法

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;
        }

        User u = userMapper.selectByName(user.getUsername());
        if (u != null) {
            map.put("usernameMsg", "用户名已被占用!");
            return map;
        }
        u = userMapper.selectByEmail(user.getEmail());
        if (u != null) {
            map.put("usernameMsg", "该邮箱已被注册!");
            return map;
        }

        //注册用户
        user.setSalt(CommunityUtil.generateUUID().substring(0, 5));
        user.setPassword(CommunityUtil.md5(user.getPassword() + user.getSalt()));
        user.setStatus(0);
        user.setType(0);
        user.setActivationCode(CommunityUtil.generateUUID());
        user.setHeaderUrl(String.format("http://images.nowcoder.com/head/%dt.png", new Random().nextInt(1000)));
        user.setCreateTime(new Date());
        userMapper.insertUser(user);

        //激活邮件
        Context context = new Context();
        context.setVariable("email", user.getEmail());
        // http://localhost:8080/community/activation/101/code
        //这里的domain是域名,在application.properties中声明为localhost
        //contextPath是项目名,这里是community
        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;
    }

邮件模板

<!doctype html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <link rel="icon" href="https://static.nowcoder.com/images/logo_87_87.png"/>
    <title>牛客网-激活账号</title>
</head>
<body>
    <div>
        <p>
            <b th:text="${email}"></b>, 您好!
        </p>
        <p>
            您正在注册牛客网, 这是一封激活邮件, 请点击 
            <a th:href="${url}">此链接</a>,
            激活您的牛客账号!
        </p>
    </div>
</body>
</html>

2.提交注册数据

注册表单
注册成功则跳转到首页,不成功则返回错误信息,并且在前台显示。
通常我们注册的时候,就算注册失败了也想保留上一次注册的信息,这里就用th:value="${user!=null?user.username:''}"实现,因为在model中已经包含了user,如果user存在的话,就可以取到里面的值。

<form class="mt-5" method="post" th:action="@{/register}">
                    <div class="form-group row">
                        <label for="username" class="col-sm-2 col-form-label text-right">账号:</label>
                        <div class="col-sm-10">
                            <input type="text" th:class="|form-control ${usernameMsg!=null?'is-invalid':''}|" id="username"
                                   th:value="${user!=null?user.username:''}"
                                   name="username" placeholder="请输入您的账号!" required>
                            <div class="invalid-feedback" th:text="${usernameMsg}">
                                该账号已存在!
                            </div>
                        </div>
                    </div>
                    <div class="form-group row mt-4">
                        <label for="password" class="col-sm-2 col-form-label text-right">密码:</label>
                        <div class="col-sm-10">
                            <input type="password" th:class="|form-control ${passwordMsg!=null?'is-invalid':''}|" id="password"
                                   th:value="${user!=null?user.password:''}"
                                   name="password" placeholder="请输入您的密码!" required>
                            <div class="invalid-feedback" th:text="${passwordMsg}">
                                密码长度不能小于8位!
                            </div>                            
                        </div>
                    </div>
                    <div class="form-group row mt-4">
                        <label for="confirm-password" class="col-sm-2 col-form-label text-right">确认密码:</label>
                        <div class="col-sm-10">
                            <input type="password" class="form-control" id="confirm-password" placeholder="请再次输入密码!" required>
                            <div class="invalid-feedback">
                                两次输入的密码不一致!
                            </div>
                        </div>
                    </div>
                    <div class="form-group row">
                        <label for="email" class="col-sm-2 col-form-label text-right">邮箱:</label>
                        <div class="col-sm-10">
                            <input type="email" th:class="|form-control ${emailMsg!=null?'is-invalid':''}|" id="email" name="email"
                                   th:value="${user!=null?user.email:''}"
                                   placeholder="请输入您的邮箱!" required>
                            <div class="invalid-feedback" th:text="${emailMsg}">
                                该邮箱已注册!
                            </div>
                        </div>
                    </div>
                    <div class="form-group row mt-4">
                        <div class="col-sm-2"></div>
                        <div class="col-sm-10 text-center">
                            <button type="submit" class="btn btn-info text-white form-control">立即注册</button>
                        </div>
                    </div>
                </form>

3.激活注册账号

//激活逻辑
    public int activation(int userId, String code) {
        User user = userMapper.selectById(userId);
        if (user.getStatus() == 1) {
            return ACTIVATION_REPEAT;
        } else if (user.getActivationCode().equals(code)) {
            userMapper.updateStatus(userId, 1);
            clearCache(userId);
            return ACTIVATION_SUCCESS;
        } else {
            return ACTIVATION_FAILURE;
        }
    }

激活的controller

    @RequestMapping(value = "/activation/{userId}/{code}", method = RequestMethod.GET)
    public String activation(Model model,
                             @PathVariable("userId") int userId,
                             @PathVariable("code") 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";
    }
@RequestMapping(value = "/login", method = RequestMethod.GET)
    public String getLoginPage() {
        return "site/login";
    }

2.演示

1.点击注册按钮
图片说明
2.填写注册信息
图片说明