当前位置: 首页 > news >正文

项目篇:Echo论坛系统项目

一、登录注册模块

1、注册功能

1.1、注册流程图

 

1.2、注册代码

/*** 用户注册* @param user* @return Map<String, Object> 返回错误提示消息,如果返回的 map 为空,则说明注册成功*/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("emailMsg", "该邮箱已被注册");return map;}// 注册用户user.setSalt(CommunityUtil.generateUUID().substring(0, 5)); // saltuser.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/%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/echo/activation/用户id/激活码String url = domain + contextPath + "/activation/" + user.getId() + "/" + user.getActivationCode();context.setVariable("url", url);String content = templateEngine.process("/mail/activation", context);mailClient.sendMail(user.getEmail(),"激活 Echo 账号", content);return map;}

2、登录模块

2.1、登录页面

2.2、登录验证码问题

        首先,登录的时候会随机生成验证码,如何把这个验证码和当前用户对应起来,实现验证码的校验呢?

        显然,由于这个时候用户还没有登录,我们是没有办法通过用户的 id 来唯一的对应它的验证码的。所以这个时候我们考虑生成一个随机的 id 来暂时的代替这个用户,将其id和对应的验证码暂时存入 Redis 中(60s)。并且在 Cookie中暂时存一份为这个用户生成的随机 id(60s)。

        其中生成验证码和进行校验分别是两个URL请求地址。

        这样,当用户点击登录按钮后,就会去 Redis中获取这个随机 id和验证码,去Cookie查询对应的验证码,判断用户输入的验证码是否一致。

2.3、登录认证并持有用户状态问题

        用户输入用户名和密码并且校验完验证码之后,就登录成功了,那我们如何在一次请求中去保存这个用户的状态?如何回显用户的信息呢?

做法可以设计一个类如下图:

        解释一下,每个用户登录成功后,我们都会为其生成一个随机的唯一的登录凭证实体类对象 LoginTicket(包含用户 id、登录凭证字符串 ticket、是否有效、过期时间),我们把这个登录凭证实体类对象永久的存储在 Redis 中(key 就是登录凭证字符串 ticket)。而所谓登录凭证的无效,就是指用户登出后,这个凭证就会被设置为无效状态;凭证的默认过期时间是 30分。

        存储完 LoginTicket 后,我们就可以根据它来获取用户的状态了。我们定义了一个拦截器 LoginTicketInterceptor每次请求之前都会从 Redis获取到 ticket,然后根据 ticket 去 Redis 中查看这个用户的登录凭证 LoginTicket 是否过期和是否有效,只有登录凭证有效且没有过期才会执行请求,不然就会跳转到登录界面。

        如果该用户的登录凭证有效且没有过期,那我们就可以在本次请求中持有这个用户的信息了。如何持有呢?这里我们考虑使用 ThreadLocal 保存用户信息,ThreadLocal 在每个线程中都创建了一个用户信息副本,也就是说每个线程都可以访问自己内部的用户信息副本变量,从而实现了线程隔离,来看下 HostHolder 类:

        所以将登录成功后要保存的信息为:

        将生成的凭证保存到Redis上,并且设置过期时间,置state为1,其中key为凭证,value为LoginTicket 类。

       然后每次请求首先经过拦截器,通过Cookie获取ticket凭证。凭借ticket凭证从Redis获取LoginTicket 类的信息。如果存在就将通过LoginTicket 类的用户id查询用户信息其保存到ThreadLocal中,否则拦截。

2.4、退出功能

        从Redis删除凭证信息,执行ThreadLocal的remove()方法清空用户信息,删除Cookie保存的凭证信息。

2.5、性能优化

        因为每次请求需要在拦截器中通过通过Cookie获取凭证,然后去Redis获取LoginTicket 类。如果通过验证则会每次去数据库查询用户信息,这样导致每一次请求访问都会去数据库查询造成巨大的访问压力。

        为了避免这种情况,所以拦截器首先去Redis查询用户信息,如果有则直接保存到ThreadLocal,否则再去数据库查询用户信息,再保存到Redis中。

2.5、流程

  • 用户登录 —> 生成登录凭证作为key存入 Redis,value是凭证类信息,Cookie 中存一份 ticket凭证
  • 每次执行请求之前,拦截器都会通过 Cookie 去 Redis 中查询该用户的登陆凭证是否过期和是否有效。点击记住我可以延长登录凭证的过期时间,用户退出则其登录凭证变为无效状态
  • 根据这个登录凭证对应的用户 id,去数据库中查询这个用户信息
  • 使用 ThreadLocal 在本次请求中一直持有这个用户信息
  • 优化点:每次请求前都需要去数据库查询这个用户信息,访问频率比较高,所以我们考虑把登录成功的用户信息在 Redis 中保存一会,拦截器每次查询前先去 Redis 中查询

 流程图如下图:

二、帖子模块

三、评论模块

四、私信模块

五、点赞模块

六、系统通知模块

相关文章:

项目篇:Echo论坛系统项目

一、登录注册模块 1、注册功能 1.1、注册流程图 1.2、注册代码 /*** 用户注册* param user* return Map<String, Object> 返回错误提示消息&#xff0c;如果返回的 map 为空&#xff0c;则说明注册成功*/public Map<String, Object> register(User user) {Map&l…...

数据可视化(2)

1.柱状图 #柱状图 #bar(x,height,width,*,aligncenter,**kwargs) #height柱子的高度&#xff0c;即y轴上的数据 #width数组的宽度&#xff0c;默认值0.8 #*表示后面的参数为匿名关键字&#xff0c;必须传入参数 #kwargs关键字参数x[1,2,3,4,5] height[random.randint(10,100)f…...

MD-MTSP:斑马优化算法ZOA求解多仓库多旅行商问题MATLAB(可更改数据集,旅行商的数量和起点)

一、斑马优化算法ZOA 斑马优化算法&#xff08;Zebra Optimization Algorithm&#xff0c;ZOA&#xff09;Eva Trojovsk等人于2022年提出&#xff0c;其模拟斑马的觅食和对捕食者攻击的防御行为。斑马优化算法&#xff08;Zebra Optimization Algorithm&#xff0c;ZOA&#x…...

【笔试强训选择题】Day32.习题(错题)解析

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;笔试强训选择题 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01; 文章目录 前言 一、Da…...

抖音seo账号矩阵系统源码如何开发布局?

目录 一、 抖音SEO账号矩阵系统源码的开发布局步骤如下&#xff1a; 二。 开发部署源码 三、 开发部署功能设计 1. 短视频AI智能创作 2. 托管式账号管理: 3. 数据分析 4. 智能营销获客 四。 抖音seo源码开发部署交付技术文档包含 五。 开发代码展示&#xff1a; 一、 抖…...

vue项目cdn打包优化

0.用vue ui可以查看项目打包后的情况。 1.定义包的排除 let externals {axios: axios,element-ui: ELEMENT,echarts: echarts,} configureWebpack: {externals: externals }2.配置cdn包资源 // 配置 let cdn {css: [// element-ui csshttps://unpkg.com/element-ui/lib/th…...

Android 之 MediaPlayer 播放音频与视频

本节引言&#xff1a; 本节带来的是Android多媒体中的——MediaPlayer&#xff0c;我们可以通过这个API来播放音频和视频 该类是Androd多媒体框架中的一个重要组件&#xff0c;通过该类&#xff0c;我们可以以最小的步骤来获取&#xff0c;解码 和播放音视频。它支持三种不同的…...

React中事件处理器的基本使用

在React中&#xff0c;为了提高性能&#xff0c;跨浏览器兼容性和开发体验&#xff0c;React实现了一套自己的事件机制&#xff0c;利用事件委托和合成事件的方式统一管理事件订阅和分发。 为了让组件能够响应用户的交互行为&#xff0c;React提供了一系列的事件处理器&#xf…...

RobotFramework

一、RobotFramework的简介和特点 1、关键字驱动&#xff1a; 把项目中的业务逻辑封装成一个一个的关键字&#xff0c;然后调用不同的关键字组成不同的业务 2、数据驱动 把测试数据放到excel&#xff1a;yaml文件中 通过改变文件中的数据去驱动测试用例执行 3、特点&#xff…...

【Matplotlib 绘制折线图】

使用 Matplotlib 绘制折线图 在数据可视化中&#xff0c;折线图是一种常见的图表类型&#xff0c;用于展示随着变量的变化&#xff0c;某个指标的趋势或关系。Python 的 Matplotlib 库为我们提供了方便易用的功能来绘制折线图。 绘制折线图 下面的代码展示了如何使用 Matplo…...

ARM汇编基本变量的定义和使用

一、ARM汇编中基本变量是什么? 数字变量: GBLA LCLA SETA 逻辑变量:GBLL LCLL SETL 字符串:GBLS LCLS SETLS 注意需要TAB键定义变量和行首改变值 二、使用步骤 1.引入库 代码如下(示例): GBLA led_num Reset_Handler PROCEXPORT Reset_Handler [WEA…...

排序算法汇总

每日一句&#xff1a;你的日积月累终会成为别人的望尘莫及 目录 常数时间的操作 选择排列 冒泡排列 【异或运算】 面试题&#xff1a; 1&#xff09;在一个整形数组中&#xff0c;已知只有一种数出现了奇数次&#xff0c;其他的所有数都出现了偶数次&#xff0c;怎么找到…...

cocos2d 中UserDefault在windows平台下的路径问题

在使用cocos2dx c开发项目时&#xff0c;通常使用cocos自带的UserDefault来存储一些项目所用到的一些配置信息&#xff1a;如游戏的音量&#xff0c;游戏的闯关数等... 但是windows平台下&#xff0c;测试发现如果用户的帐户名使用是中文&#xff0c;在启动程序时会报错&#…...

ChatGPT与高等教育变革:价值、影响及未来发展

最近一段时间&#xff0c;ChatGPT吸引了社会各界的目光&#xff0c;它可以撰写会议通知、新闻稿、新年贺信&#xff0c;还可以作诗、写文章&#xff0c;甚至可以撰写学术论文。比尔盖茨、马斯克等知名人物纷纷为此发声&#xff0c;谷歌、百度等知名企业纷纷宣布要提供类似产品。…...

Matlab Image Processing toolbox 下载安装方法

当安装好Matlab之后&#xff0c;发现没有Image Processing toolbox这个图像处理工具箱 从新安装一遍&#xff0c; 选上 Image Processing toolbox 但是不用选matlab即可 1.找到之前安装时的Setup安装程序包&#xff0c;按照之前安装Matlab步骤&#xff0c;到选择需要安装的Ma…...

什么是消息键(Key)?如何使用消息键进行消息顺序性保证?

消息键&#xff08;Key&#xff09;是Kafka消息的一个可选属性&#xff0c;用于标识消息的逻辑关联关系。每条消息可以携带一个关键字作为其键&#xff0c;这个键可以是字符串、整数等数据类型。 使用消息键可以在Kafka中实现消息的顺序性保证&#xff0c;具体方式如下&#x…...

慎思笃行,兴业致远:金融行业的数据之道

《中庸》中说&#xff0c;“博学之&#xff0c;审问之&#xff0c;慎思之&#xff0c;明辨之&#xff0c;笃行之”。这段话穿越千年&#xff0c;指引着中国千行百业的发展。对于金融行业来说&#xff0c;庞大的数据量可以说是“博学”的来源。但庞大的数据体量&#xff0c;既是…...

Git-分支管理

文章目录 1.分支管理2.合并冲突3.合并模式4.补充 1.分支管理 Git分支管理是指在Git版本控制系统中&#xff0c;使用分支来管理项目的不同开发线路和并行开发的能力。通过分支&#xff0c;开发者可以在独立的环境中进行功能开发、bug修复等工作&#xff0c;而不会影响到主分支上…...

[Ubuntu 22.04] containerd配置HTTP方式拉取私仓Harbor

文章目录 1. 基础环境配置2. Docker安装3. 部署Harbor&#xff0c;HTTP访问4. 部署ContainerD5. 修改docker配置文件&#xff0c;向harbor中推入镜像6. 配置containerd6.1. 拉取镜像验证6.2. 推送镜像验证 1. 基础环境配置 [Ubuntu 22.04] 安装K8S基础环境准备脚本 2. Docker安…...

入门指南:深入解析OpenCV的copyTo函数及其与rect的应用场景

文章目录 导言copyTo函数的示例copyTo函数与rect的应用场景结论 导言 OpenCV是一个功能强大的开源计算机视觉库&#xff0c;广泛应用于图像处理和计算机视觉任务。在OpenCV中&#xff0c;copyTo函数是一个重要的图像处理函数&#xff0c;它允许我们在不同的图像之间复制像素数…...

2018年全国硕士研究生入学统一考试管理类专业学位联考写作试题——解析版

2018年1月真题 四、写作&#xff1a;第56~57小题&#xff0c;共65分。其中论证有效性分析30 分&#xff0c;论说文35分。 56.论证有效性分析&#xff1a; 分析下述论证中存在的缺陷和漏洞&#xff0c;选择若干要点&#xff0c;写一篇600字左右的文章&#xff0c;对该论证的有…...

系统集成|第七章(笔记)

目录 第七章 范围管理7.1 项目范围管理概念7.2 主要过程7.2.1 规划范围管理7.2.2 收集需求7.2.3 定义范围7.2.4 创建工作分解结构 - WBS7.2.5 范围确认7.2.6 范围控制 上篇&#xff1a;第六章、整体管理 第七章 范围管理 7.1 项目范围管理概念 概述&#xff1a;项目范围管理就…...

Qt —— Vs2017编译hiredis源码并测试调用(附调用hiredis库源码)

下载hiredis源码 编译hiredis源码 1、解压下载的hiredis源码包,如图使用Vs2017打开hiredis_win.sln 2、如下两图,Vs2017打开.sln后点击升级。 分别对两个工程的debug、release进行配置。Debug配置为多线程调试DLL(MDd)、Release配置为多线程DLL(/MD),这样做是为了配合被调用…...

深入理解设计模式:设计模式定义、设计原则以及组织编目

文章目录 一、设计模式1.1 设计模式的起源1.2 设计模式的定义1.3 记录要素1.4 合理使用模式 二、设计模式的六大原则2.1 开闭原则(Open-Closed Principle, OCP)2.1.1 定义2.1.2 原则分析2.1.3 开闭原则的意义所在 2.2 单一职责原则(Single Responsibility Principle, SRP)2.4.1…...

鸿鹄协助管理华为云与炎凰Ichiban

炎凰对华为云的需求 在炎凰日常的开发中&#xff0c;对于服务器上的需求&#xff0c;我们基本都是采用云服务。目前我们主要选择的是华为云&#xff0c;华为云的云主机比较稳定&#xff0c;提供的云主机配置也比较多样&#xff0c;非常适合对于不同场景硬件配置的需求&#xff…...

Vite创建Vue+TS项目引入文件路径报错

使用vite搭建vue3脚手架的时候&#xff0c;发现main.ts中引入App.vue编辑器会报错&#xff0c;但是不影响代码运行。 报错信息&#xff1a;TS2307: Cannot find module ‘./App.vue’ or its corresponding type declarations. 翻译过来是找不到模块或者相关的声明类型&#…...

计算机里基本硬件的组成以及硬件协同

文章目录 冯诺依曼体系输入设备输出设备存储器运算器控制器协同工作的流程 冯诺依曼体系 世界上第一台通用计算机&#xff0c;ENIAC&#xff0c;于1946年诞生于美国一所大学。 ENIAC研发的前期&#xff0c;需要工作人员根据提前设计好的指令手动接线&#xff0c;以这种方式输入…...

2023软件设计师中级备考经验分享(文中有资料链接分享)

先摊结论吧&#xff0c;软考中级设计师备考只是备考半个月&#xff08;期间还摆烂了几天&#xff09;&#xff0c;然而成绩如下&#xff1a; 我自己都没想到会这么好的成绩。。。 上午题&#xff1a;推荐把软考通APP里的历年真题刷3-4遍&#xff0c;直接刷真题&#xff0c;然后…...

Windows 10 中无法最大化任务栏中的程序

方法1&#xff1a;仅选择选项 PC 屏幕 如果您使用双显示器&#xff0c;有时这可能会发生在您的 1 台计算机已插入但您正在访问的应用程序正在另一台计算机上运行的情况下&#xff0c;因此您看不到任何选项。因此&#xff0c;请设置仅在主计算机上显示显示的 PC 屏幕选项。 第…...

【iOS】KVOKVC原理

1 KVO 键值监听 1.1 KVO简介 KVO的全称是Key-Value Observing&#xff0c;俗称"键值监听"&#xff0c;可以用于监听摸个对象属性值得改变。 KVO一般通过以下三个步骤使用&#xff1a; // 1. 添加监听 [self.student1 addObserver:self forKeyPath:"age"…...

低价代网站/网络推广优化方案

## 环境要求 - Unix, Linux 或 Windows - Web服务器&#xff1a;Apache 1.3 或更高的版本 - PHP&#xff1a;5.2或更高版本 - MySQL&#xff1a;5.0或更高版本 PrestaShop也可以在Microsoft的 IIS Web server 6.0或更高版本&#xff0c;及nginx 1.0或更高版本上运行。 这些软件…...

武汉p2p网站制作公司/免费网站安全软件大全游戏

文章目录一、JVM线程通常有六种状态二、Java中sleep,wait,yield,join的区别一、JVM线程通常有六种状态 New&#xff08;新建&#xff09;: 尚未启动的线程的线程状态。 Runnable&#xff08;可运行&#xff09;: 可运行线程的线程状态&#xff0c;等待CPU调度。 Blocked&…...

wordpress自适应画廊/点击宝seo

SpringClod之服务保护框架HystrixHystrix服务保护概念服务雪崩效应服务降级服务熔断服务隔离Hystrix环境搭建fallback接口Hystrix Hystrix是Netflix开源的高可用框架,能够完美解决分布式系统架构中高可用服务的问题 断路器服务降级服务熔断服务隔离机制服务雪崩效应 Hystrix具…...

海安做网站/重庆seo俱乐部

import cv2 import numpy as npimg_rgb = cv2.imread(2.jpg) #模板 img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)template = cv2.imread(liuyan3.jpg,0...

网站建设的难点/网站优化推广公司

JAVA中锁是 在并发编程中&#xff0c;经常会遇到多个线程访问同一个共享变量&#xff0c;当同时对共享变量进行读写操作时&#xff0c;就会产生数据不一致的情况。 为了解决这个问题 JDK 1.5 之前&#xff0c;使用 synchronized 关键字&#xff0c;拿到 Java 对象的锁&#x…...

郑州外贸网站建设/seo搜索引擎优化技术教程

前言有一段时间没有写博客了&#xff0c;整天都在忙&#xff0c;上班&#xff0c;录制课程&#xff0c;恰巧最近一段时间比较清闲&#xff0c;打算弄弄MYSQL数据库。关于MySQL数据库&#xff0c;这里就不做过多的介绍&#xff0c;开源、免费等特性深受各个互联网行业喜爱&#…...