仿牛客项目Day3:开发社区登录模块

news2024/10/1 17:39:54

发送邮件

邮箱设置

springEmail

properties

spring.mail.host=smtp.qq.com
spring.mail.port=465
spring.mail.username=
spring.mail.password=
spring.mail.protocol=smtps
spring.mail.properties.mail.smtp.ssl.enable=true

MailClient

@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());
        }
    }
}

 先初始化message,然后把message交给helper

helper可以设置发送方from,接收方to,标题subject,内容content,true是表示能不能接收html文件

然后用mailSender.send来发送邮件

MailTest

@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = CommunityApplication.class)
public class MailTests {

    @Autowired
    private MailClient mailClient;

    @Test
    public void testTextMail(){
        mailClient.sendMail("", "TEST", "Welcome");
    }
}

模版引擎:发送html

MailTest

    
    @Autowired
    private MailClient mailClient;

    @Autowired
    private TemplateEngine templateEngine;

    @Test
    public void textHtmlMail(){
        Context context = new Context();
        context.setVariable("username", "sunday");

        String content = templateEngine.process("/mail/demo", context);
        System.out.println(content);

        mailClient.sendMail("", "HTML", content);

    }

先把username值传到html文件中,然后拼接出来,最后传content这个html文件,helper那里设置成了true

开发注册功能

访问注册页面

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

直接由controller调用模板,响应html页面就可以

LoginController.java

    @RequestMapping(path = "/register", method = RequestMethod.GET)
    public String getRegisterPage() {
        return "/site/register";
   

register.html

 改一下

<html lang="en" xmlns:th="http://www.thymeleaf.org">

改一下css和js的数据格式

<link rel="stylesheet" th:href="@{/css/global.css}" />
<link rel="stylesheet" th:href="@{/css/login.css}" />

index.html

可以通过header复用

在register.html复用

提交注册数据

前期准备

引入判断空值什么的包

		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.9</version>
		</dependency>

把链接做成可配置的,在properties里面

community.path.domain=http://localhost:8080

写一个工具类,用于生成随机字符串和md5加密

服务端验证账号是否已存在、邮箱是否已注册

注册是对用户表进行操作->操作UserService层

 

通过表单提交数据

服务端发送激活邮件

UserService.java

LoginController.java

    @RequestMapping(path = "/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"; // 成功之后return到一个第三方页面
        } else {
            model.addAttribute("usernameMsg", map.get("usernameMsg"));
            model.addAttribute("passwordMsg", map.get("passwordMsg"));
            model.addAttribute("emailMsg", map.get("emailMsg"));
            return "/site/register";
        }
    }

 operate-result.html

		<!-- 内容 -->
		<div class="main">
			<div class="container mt-5">
				<div class="jumbotron">
					<p class="lead" th:text="${msg}">您的账号已经激活成功,可以正常使用了!</p>
					<hr class="my-4">
					<p>
						系统会在 <span id="seconds" class="text-danger">8</span> 秒后自动跳转,
						您也可以点此 <a id="target" th:href="@{${target}}" class="text-primary">链接</a>, 手动跳转!
					</p>
				</div>
			</div>
		</div>

 register.html

<!-- 内容 -->
		<div class="main">
			<div class="container pl-5 pr-5 pt-3 pb-3 mt-3 mb-3">
				<h3 class="text-center text-info border-bottom pb-3">注&nbsp;&nbsp;册</h3>
				<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':''}|"
								   th:value="${user!=null?user.username:''}"
								   id="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':''}|"
								   th:value="${user!=null?user.password:''}"
								   id="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"
								   th:value="${user!=null?user.password:''}"
								   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':''}|"
								   th:value="${user!=null?user.email:''}"
								   id="email" name="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>				
			</div>
		</div>

 确定表单的提交方式

每一个框都要有相应的name,这些name要和controller中user对象的属性名对应

 

如果usernameMsg是非空的就加上is-invalid

因为如果usernameMsg是空的话,说明没错误,下面的div就显示不出来,有一个连带关系

激活注册账号

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

已经发送链接之后,说明前面注册的功能已经完成了,现在要对一个url进行验证,有三种情况:

  1. 激活成功
  2. 这个链接已经被验证过
  3. 无效链接

现在util包里面写出激活的三个常量

public interface CommunityConstant {

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

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

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

}

这三个变量有什么卵用呢?为什么三个常量还要给一个高大上的名字呢?

userservice

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

这个函数是通过controller层的userid和那个user对应的生成的code,从数据库中看那个user的status属性,如果是1的话,就说明重复添加了,返回repeat;如果user的status初始值是0,而且它传入的code和数据库里面user的code是一样的话,就说明还没有被激活,此时就要把这个status设成1,返回success;如果code不一样,就说明是一个假冒伪劣网址,就要返回failure

loginController

    // http://localhost:8080/community/activation/101/code
    @RequestMapping(path = "/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";
    }

这个controller就要从service层获取activation方法值了,传递的是ul里面的userid和code,这个url是由上面userservice层拼出来的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1505589.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机网络——OSI网络层次模型

计算机网络——OSI网络层次模型 应用层表示层会话层传输层TCP和UDP协议复用分用 网络层数据链路层物理层OSI网络层次模型中的硬件设备MAC地址和IP地址MAC地址IP地址MAC地址和IP地址区别 OSI网络层次模型通信过程解释端到端点到点端到端和点到点的区别 我们之前简单介绍了一下网…

数组:初始化,访问某一个,遍历

文章目录 静态初始化数组数组的访问&#xff1a;遍历数组案例 动态初始化数组总结案例 静态初始化数组 定义数组的时候直接给数组赋值。 简化格式&#xff1a; int[] ages {12,52,96}; 完整格式&#xff1a; int[] ages new int[]{12,16,26};数组变量名中存储的是数组在内存…

LINUX ADC使用

监测 ADC ,使用CAT 查看&#xff1a; LINUX ADC基本使用 &adc {pinctrl-names "default";pinctrl-0 <&adc6>;pinctrl-1 <&adc7>;pinctrl-2 <&adc8>;pinctrl-3 <&adc9>;pinctrl-4 <&adc10>;pinctrl-5 …

xxl-job学习记录

1、应用场景 例&#xff1a; 某收银系统需要在每天凌晨统计前一天的财务分析、汇总 某银行系统需要在信用卡还款日前三天发短信提醒等 2、为什么需要使用任务调度 spring中提供了注解Scheduled的注解&#xff0c;这个注解也可以实现定时任务的执行 我们只需要在方法上使用这…

安全加速SCDN在网站运营中的重要作用

SCDN&#xff08;Secure Content Delivery Network&#xff09;是一种安全加速技术&#xff0c;对于网站运营起到非常重要的作用。它能够提升用户体验&#xff0c;保护网站安全&#xff0c;提高网站的性能和可靠性。本文将详细介绍SCDN在网站运营中的作用。 首先&#xff0c;SC…

STM32基础--启动文件详解

启动文件简介&#xff08;我的建议是记住这个就行&#xff09; 启动文件由汇编编写&#xff0c;是系统上电复位后第一个执行的程序。主要做了以下工作&#xff1a; 初始化堆栈指针 SP_initial_sp &#xff08;没错就是你机组学的那个堆栈指针&#xff09;初始化 PC 指针 Rese…

《vtk9 book》 官方web版 第3章 - 计算机图形基础 (4 / 6)

3.10 将所有内容整合起来 本节概述了图形对象以及如何在 VTK 中使用它们。 图形模型 我们已经讨论了许多在场景渲染中起作用的对象。现在是将它们整合到一个全面的图形和可视化对象模型中的时候了。 在可视化工具包中&#xff0c;有七个基本对象用于渲染场景。幕后有许多其他对…

【开发】JavaWeb开发中如何解析JSON格式数据

目录 前言 JSON 的数据类型 Java 解析 JSON 常用于解析 JSON 的第三方库 Jackson Gson Fastjson 使用 Fastjson Fastjson 的优点 Fastjson 的主要对象 JSON 接口 JSONObject 类 JSONArray 类 前言 1W&#xff1a;什么是JSON&#xff1f; JSON 指 JavaScrip t对象表…

c++0305习题

一、求下面表达式的值 1&#xff0e;0 2&#xff0e;-1 3&#xff0e;1 4&#xff0e;&#xff08;1&#xff09;1 &#xff08;2&#xff09;3.2 &#xff08;3&#xff09;0 &#xff08;4&#xff09;7.0 5.&#xff08;1&#xff09;0&#xff08;2&#xff09;300.005&a…

【蓝桥·算法双周赛】第七场分级赛——小白入门赛

2.霓虹【算法赛】 - 蓝桥云课 (lanqiao.cn) st数组用来存第i个位置&#xff0c;这个字母有没有编号j #include<bits/stdc.h> const int N1e610; using lllong long; std::map<std::string,std::string> mp;std::string a,aa; int st[N][10];// int stt[N][10];//对…

Tensorflow2.0+部署(tensorflow/serving)过程备忘记录Windows+Linux

Tensorflow2.0部署&#xff08;tensorflow/serving&#xff09;过程备忘记录 部署思路&#xff1a;采用Tensorflow自带的serving进模型部署&#xff0c;采用容器docker 1.首先安装docker 下载地址&#xff08;下载windows版本&#xff09;&#xff1a;https://desktop.docke…

算法设计与分析---递归算法

递归算法 排列问题&#xff1a; 设计递归算法生成n个元素R{r1,r2,r3…rn}的全排列 将排列R个元素拆解为RiR-{ri}个元素的全排列 &#xff08;r)perm(X)表示在全排列perm(X)的每一个排列前加上前缀得到的排列 汉诺塔问题&#xff1a; void hanoi(int n,int a,int b,int c) …

第八个实验:(A+B)-C的结果判断奇偶特性

实验内容:(A+B)-C的结果判断奇偶特性,最后显示结果 实验步骤: 第一步:建立项目 第二步:实验步骤,编写程序 第三步:实验结果

【FindAllMarkers】Seruat鉴定差异表达基因的方法与P值的理解

目录 差异表达分析 用法简单示例 结果解读 P值与P adjust值的区别 假设检验 Bonferroni校验 reference 差异表达分析 seruat中差异表达分析的函数主要有两个&#xff1a;FindAllMarkers()和FindMarkers()&#xff0c;前者是比较一个cluster与所有其他cluster之间的基因…

鸿蒙开发(一)-环境配置

鸿蒙开发(一)-环境配置 本篇文章主要介绍下鸿蒙开发环境的配置。 1&#xff1a;下载DevEco Studio 可以直接访问以下网址下载&#xff1a; https://developer.huawei.com/consumer/cn/deveco-studio#download 当前window的使用版本是&#xff1a;devecostudio-windows-3.1…

Openharmony的设备开发流程 Hi3516DV300

安装VirtualBox 这里用VirtualBox 6.1.3 https://download.virtualbox.org/virtualbox/6.1.30/VirtualBox-6.1.30-148432-Win.exe 安装 安装Ubuntu镜像 Ubuntu系统要求&#xff1a;Ubuntu18.04~21.10版本。推荐使用20.04版本&#xff0c;内存16 GB及以上。 https://mirrors…

错误票据 刷题笔记

开数组 读入数据 记录最小值和最大值 每次读入x; 让a[x]; 从最小值开始 向上扫 当扫到a[x]0时候为断号 扫到a[x]>1为重号&#xff1b; 该题的小技巧 未知长度的数据的读入方式 1.首先在头文件敲上 #include<sstream> #include<string> #include<…

SpringCloudGateway理论与实践

文章目录 网关介绍为什么需要网关Gateway 使用gateway pom依赖yml 配置重启测试总结 断言过滤器工厂路由过滤器的种类请求头过滤器默认过滤器全局过滤器总结 Gateway解决跨域 网关介绍 Spring Cloud Gateway 是一个基于Spring Framework 5&#xff0c;由Spring Cloud团队开发的…

FPGA - 科学设计复位信号(XILINX)

1&#xff0c;同步复位与异步复位 简单来说&#xff1a;复位信号与时钟同步&#xff0c;称之为同步复位。 复位信号与时钟不同步&#xff0c;称之为异步复位。 2、xilinx 的复位策略 ① 同步高复位 ② 计数器和状态机必须复位 ③ 能不使用复位尽量不使用复位&#xff0c;比如中…

一键部署Tesseract-OCR环境C++版本(Windows)

环境&#xff1a;Windows 10 工具&#xff1a;git vcpkg vscode cmake 库&#xff1a;Tesseract 一键部署Tesseract-OCR环境C版本&#xff08;Windows&#xff09; 分享这篇文章的原因很简单&#xff0c;就是为了让后续的朋友少走弯路。自己在搜索相关C版本的tesseract部署时…