2.开发社区登录模块


项目源码可以在 https://gitee.com/ShayneC/community获取

2.开发社区登录模块

1. 发送邮件

  • 邮箱设置

    • 启用客户端SMTP服务
  • Spring Email

    • 导入 jar 包
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-mail</artifactId>
    </dependency>
    
    • 邮箱参数配置
    # MailProperties
    [email protected]
    spring.mail.password=xxxxxxxxxxxx  // 授权密码,非登录密码
    spring.mail.host=smtp.qq.com
    spring.mail.properties.mail.smtp.ssl.enable=true
    
    
    
    • 使用 JavaMailSender 发送邮件

    • 模板引擎

      • 使用 Thymeleaf 发送 HTML 邮件

    在src/main/java/com/nowcoder/community在新建一个util包,并创建MailClient类

    package com.nowcoder.community.util;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.mail.javamail.JavaMailSender;
    import org.springframework.mail.javamail.MimeMessageHelper;
    import org.springframework.stereotype.Component;
    
    import javax.mail.MessagingException;
    import javax.mail.internet.MimeMessage;
    
    @Component
    public class MailClient {
    
        private static final Logger logger = LoggerFactory.getLogger(MailClient.class);
    
        @Autowired
        private JavaMailSender mailSender;
    
        @Value("${spring.mail.username}")
        private String from;
    
        public void sendMail(String to, String subject, String content) {
            try {
                MimeMessage message = mailSender.createMimeMessage();
                MimeMessageHelper helper = new MimeMessageHelper(message);
                helper.setFrom(from);
                helper.setTo(to);
                helper.setSubject(subject);
                helper.setText(content, true);
                mailSender.send(helper.getMimeMessage());
            } catch (MessagingException e) {
                logger.error("发送邮件失败:" + e.getMessage());
            }
        }
    }
    

    在src/main/resources/templates/demo下创建testMail.html文件

    <!DOCTYPE html>
    <html lang="en" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>html邮件</title>
    </head>
    <body>
        <p>欢迎你, <span style="color: red" th:text="${name}"></span></p>
    </body>
    </html>
    

    在src/test/java/com/nowcoder/community下新建MailTests类,进行测试

    package com.nowcoder.community;
    
    import com.nowcoder.community.util.MailClient;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.ContextConfiguration;
    import org.thymeleaf.TemplateEngine;
    import org.thymeleaf.context.Context;
    
    @SpringBootTest
    @ContextConfiguration(classes = CommunityApplication.class)
    public class MailTests {
    
        @Autowired
        private MailClient mailClient;
    
        @Autowired
        private TemplateEngine templateEngine;
    
        @Test
        public void testTextMail() {
            mailClient.sendMail("[email protected]", "测试主题", "<h1>测试内容</h1>");
            System.out.println("发送成功");
        }
    
        @Test
        public void testHtmlMail() {
            Context context = new Context();
            context.setVariable("name", "ShayneC");
            String content = templateEngine.process("/demo/testMail", context);
            System.out.println(content);
            mailClient.sendMail("[email protected]", "html测试", content);
        }
    }
    

2. 开发注册功能

  • 访问注册页面
    • 点击顶部区域内的链接,打开注册页面。

在src/main/java/com/nowcoder/community/controller中创建LoginController,并修改相应的index.html和register.html文件。

package com.nowcoder.community.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class LoginController {

    @GetMapping("/register")
    public String getRegisterPage() {
        return "/site/register";
    }
}
  • 提交注册数据
    • 通过表单提交数据。

导入工具类

<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.12.0</version>
</dependency>

在src/main/java/com/nowcoder/community/util下新建CommunityUtil类

package com.nowcoder.community.util;

import org.apache.commons.lang3.StringUtils;
import org.springframework.util.DigestUtils;

import java.util.UUID;

public class CommunityUtil {

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

    // MD5加密
    // hello -> abc123def456
    // hello + 12d9k -> abc123def456gsd
    public static String md5(String key) {
        if (StringUtils.isBlank(key)) {
            return null;
        }
        return DigestUtils.md5DigestAsHex(key.getBytes());
    }
}

自定义域名

# community
community.path.domain=http://localhost:8888

向UserService中注入所需要的组件

package com.nowcoder.community.service;

import com.nowcoder.community.dao.UserMapper;
import com.nowcoder.community.entity.User;
import com.nowcoder.community.util.MailClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;

@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private MailClient mailClient;

    @Autowired
    private TemplateEngine templateEngine;

    @Value("${community.path.domain}")
    private String domain;

    @Value("${server.servlet.context-path}")
    private String contextPath;

    public User findUserById(int id) {
        return userMapper.selectById(id);
    }
}
  • 服务端验证账号是否已存在、邮箱是否已注册。
  • 服务端发送激活邮件。

在UserSerice中添加register方法,验证注册逻辑,同时修改register.html

public Map<String, Object> register(User user) {
   
    HashMap<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("emailMsg", "该邮箱已被注册");
        return map;
    }

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

    // 激活邮件
    Context context = new Context();
    context.setVariable("email", user.getEmail());
    // http://localhost:8888/community/activation/101/code
    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;
}

将UserService组件注入到LoginController中并添加在register页面提交表单的方法。

在注册成功后让页面跳转到operate-result.html页面,同时修改register.html页面。

package com.nowcoder.community.controller;

import com.nowcoder.community.entity.User;
import com.nowcoder.community.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

import java.util.Map;

@Controller
public class LoginController {
   

    @Autowired
    private UserService userService;

    @GetMapping("/register")
    public String getRegisterPage() {
   
        return "/site/register";
    }

    @PostMapping("/register")
    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";
        }
    }
}

激活注册账号

  • 点击邮件中的链接,访问服务端的激活服务。

为了记录通过邮件激活的状态,在src/main/java/com/nowcoder/community/service中创建CommunityConstant接口

package com.nowcoder.community.service;

public interface CommunityConstant {
   

    /**
     * 激活成功
     */
    int ACTIVATION_SUCCESS = 0;

    /**
     * 重复激活
     */
    int ACTIVATION_REPEAT = 1;

    /**
     * 激活失败
     */
    int ACTIVATION_FAILURE = 2;
}

并让UserService实现CommunityConstant接口,同时添加激活的方法

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);
        return ACTIVATION_SUCCESS;
    } else {
   
        return ACTIVATION_FAILURE;
    }
}

UserService类

package com.nowcoder.community.service;

import com.nowcoder.community.dao.UserMapper;
import com.nowcoder.community.entity.User;
import com.nowcoder.community.util.CommunityUtil;
import com.nowcoder.community.util.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
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值