<<<<<<< HEAD
[]( )
# 项目总结
实现了一个功能完善的在线论坛,旨在为校园内提供一个“畅所欲言”的论坛环境,项目分别实现了用户模块、登录模块、发帖模块、和点赞关注模块等。
主要的技术点:
登录注册功能:使用kaptcha去生成验证码,使用SpringMail完成注册
Redis优化验证码的保存,解决分布式session问题
使用拦截器拦截用户请求,将用户信息绑定在ThreadLocal上
构建Trie数据结构,实现对发表帖子评论的敏感词过滤
支持对帖子评论,也支持对评论进行回复
利用Redis的zset并结合Redis实现点赞关注的功能
用户点赞关注后,使用kafka实现异步的发送系统通知
# 开发环境
构建工具:Apache Maven
集成开发工具: IntelliJ IDEA 2021
数据库:MySQL、Redis
应用服务器:Apache Tomcat
框架:Spring、SpringMVC、Mybatis、SpringBoot
版本控制工具:Git
## 项目准备
工作环境的配置,IDE使用IntellijIDEA,JDK使用JDK8,具体框架以及MySQL,Redis,kafka的版本与配置,维持当下较新的版本,文章主要介绍主要模块后端代码的实现部分。
# 一、注册与登录功能的实现
注册和登录功能是每个项目最基本的功能,实现的主要难点在于怎么解决分布式Session问题,密码安全问题,以及怎么优化登录的问题。
**用户表实现**
id | username | password |salt | email |type |status | activation_code | header_url |create_time |
-------- | ----- | ----- | ----- | ----- | ----- | ----- | ----- | -----| -----
## 密码实现
为了保证安全,密码不能明文的在网络中进行传输,也不能以明文的形式存到数据库中。
存在数据库的密码 = MD5( 密码 + salt ) 防止密码泄露,salt为随机字符串
```java
// MD5 加密
public static String md5(String key) {
if (StringUtils.isBlank(key)) {
return null;
}
return DigestUtils.md5DigestAsHex(key.getBytes());
}
```
## SpringMail配置及发送注册邮件
application.properties对SpringMail进行配置
```java
# mailProperties
spring.mail.host=smtp.sina.com
spring.mail.port=465
spring.mail.username=wfb18324952938@sina.cn
spring.mail.password=4681082336c1****
spring.mail.protocol=smtps
spring.mail.properties.mail.smtp.ssl.enable=true
```
MailClient实现方法,进行发送邮件操作
```java
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());
}
}
```
## 会话管理
由于Http是无状态的,每次的http请求之间信息不共享,为了保证用户每次请求不用重新输入账号密码,保存用户的登录状态,就会有session和cookie这样的机制,去保存用户登录信息,但是在分布式部署的时候就会存在session共享的一个问题。
![session共享](https://img-blog.csdnimg.cn/bf5201c86a6c494a8cd0037ee12ec189.png)
现在网站基本是多台服务器分布式部署的,如果将用户信息存到session中,而session是存到服务器上,在分布式环境下,由于各个服务器主机之间的信息并不共享,将用户信息存到服务器1上,同一个用户的下一个请求过来的时候,由于nginx的负载均衡策略,去请求了服务器2,就找不到之前的session了。
**解决办法:**
将客户端会话数据不存到Session中而是存到数据库中
![找不到session](https://img-blog.csdnimg.cn/5115244c969945fd929124847577d2ed.png)
考虑到关系型数据库性能较慢,项目中采用的方式是存到redis中
## Kaptcha生成验证码
利用Kaptcha类实现生成随机字符,生成图片(验证码功能)
```java
public Producer kaptchaProducer(){
Properties properties = new Properties();
properties.setProperty("kaptcha.image.width","100");
properties.setProperty("kaptcha.image.height","40");
properties.setProperty("kaptcha.textproducer.font.size","32");
properties.setProperty("kaptcha.textproducer.font.color","black");
properties.setProperty("kaptcha.textproducer.char.string","0123456789ABCDEFGHJKLMNOPQRSTUVWXYZ");
properties.setProperty("kaptcha.textproducer.char.length","4");
properties.setProperty("kaptcha.noise.impl","com.google.code.kaptcha.impl.NoNoise");
DefaultKaptcha kaptcha = new DefaultKaptcha();
Config config = new Config(properties);
kaptcha.setConfig(config);
return kaptcha;
}
```
## Loginticket生成凭证 记录登录状态
本项目中先采用将用户登录信息存到数据库的login_ticket表中,后续采用存到redis中优化。
**V1 将用户登录凭证ticket存到mysql的login_ticket表中**
登陆成功的时候生成登录凭证,生成Loginticket往数据库login_ticket存,并且被设置为cookie,下次用户登录的时候会带上这个ticket,ticket是个随机的UUID字符串,有过期的时间expired和有效的状态status
**LoginTicket表**
id | user_id| ticket|status| expired|
-------- | ----- | ----- | ----- | ----- |
**V2: 使用Redis优化登录模块**
- 使用Redis存储验证码
* 验证码需要频繁的访问与刷新,对性能要求比较高
* 验证码不需要永久保存,通常在很短的时间后就会失效(redis设置失效时间)
* 分布式部署的时候,存在Session共享的问题(之前验证码是存到session里面,使用redis避免session共享问题)
Key| Value|
-------- | -----|
Kaptcha:owner| String
直接将验证码字符串存到session当中,每次都是从session中获取验证码字符串的值在进行判断会出现分布式session的问题,比如说刷新验证码是一次请求,此次请求将验证码存到了服务器A的session当中,但在点击登录按钮,去触发登录请求s时,将此次请求转到了服务器B,而服务器B并没有存储验证码的session,就会出现无法判断的问题。
```java
// 验证码的归属
String kaptchaOwner = CommunityUtil.generateUUID();
Cookie cookie = new Cookie("kaptchaOwner", kaptchaOwner);
cookie.setMaxAge(60);
cookie.setPath(contextPath);
response.addCookie(cookie);
// 将验证码存入Redis
String redisKey = RedisKeyUtil.getKaptchaKey(kaptchaOwner);
redisTemplate.opsForValue().set(redisKey, text, 60, TimeUnit.SECONDS);
```
- 使用Redis存储登录凭证,作废login_ticket
* 处理每次请求的时候,都要从请求的cookie中取出登录凭证并与从数据库mysql中查询用户的登录凭证作比对,访问的频率非常高,ticket如果用redis存,mysql就可以不用存了,login_ticket可以作废
```java
// 生成登录凭证
LoginTicket loginTicket = new LoginTicket();
loginTicket.setUserId(user.getId());
loginTicket.setTicket(CommunityUtil.generateUUID());
loginTicket.setStatus(0);
loginTicket.setExpired(new Date(System.currentTimeMillis() + expiredSeconds * 1000));
// 舍弃将LoginTicket通过Mapper存入MySQL,转而放入Redis里
// loginTicketMapper.insertLoginTicket(loginTicket);
String redisKey = RedisKeyUtil.getTicketKey(loginTicket.getTicket());
// loginTicket会序列化为JSON字符串
redisTemplate.opsForValue().set(redisKey, loginTicket);
map.put("ticket", loginTicket.getTicket());
return map;
```
- 使用Redis缓存用户信息
* 处理每次请求的时候,都要根据登录凭证查询用户信息,访问的频率非常高(每�
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
实现了一个功能完善的在线论坛,旨在为校园内提供一个“畅所欲言”的论坛环境,项目分别实现了用户模块、登录模块、发帖模块、和点赞关注模块等。 主要的技术点: 登录注册功能:使用kaptcha去生成验证码,使用SpringMail完成注册 Redis优化验证码的保存,解决分布式session问题 使用拦截器拦截用户请求,将用户信息绑定在ThreadLocal上 构建Trie数据结构,实现对发表帖子评论的敏感词过滤 支持对帖子评论,也支持对评论进行回复 利用Redis的zset并结合Redis实现点赞关注的功能 用户点赞关注后,使用kafka实现异步的发送系统通知 开发环境 构建工具:Apache Maven 集成开发工具: IntelliJ IDEA 2021 数据库:MySQL、Redis 应用服务器:Apache Tomcat 框架:Spring、SpringMVC、Mybatis、SpringBoot 版本控制
资源推荐
资源详情
资源评论
收起资源包目录
SpringBoot+MySQL+Redis+MyBatis实现的校园论坛项目源代码+详细使用说明文档 (122个子文件)
mvnw.cmd 7KB
global.css 2KB
discuss-detail.css 243B
letter.css 181B
login.css 36B
.gitignore 395B
index.html 15KB
discuss-detail.html 13KB
my-post.html 13KB
my-reply.html 11KB
register.html 11KB
followee.html 10KB
follower.html 10KB
letter.html 10KB
letter-detail.html 9KB
notice.html 9KB
setting.html 8KB
notice-detail.html 8KB
search.html 8KB
login.html 8KB
profile.html 7KB
forget.html 7KB
data.html 7KB
operate-result.html 6KB
404.html 6KB
500.html 5KB
ajax-demo.html 798B
activation.html 479B
forget.html 427B
student.html 421B
demo.html 246B
view.html 219B
maven-wrapper.jar 57KB
MessageController.java 11KB
UserService.java 8KB
LoginController.java 6KB
DiscussPostController.java 6KB
AlphaController.java 6KB
UserController.java 5KB
ElasticsearchService.java 5KB
SensitiveFilter.java 5KB
SecurityConfig.java 4KB
AlphaService.java 4KB
ElasticsearchTests.java 4KB
MapperTests.java 4KB
DataService.java 3KB
EventConsumer.java 3KB
LoginTicketInterceptor.java 3KB
FollowService.java 3KB
CommentController.java 3KB
RedisKeyUtil.java 2KB
RedisTests.java 2KB
HomeController.java 2KB
LikeService.java 2KB
CommunityApplicationTests.java 2KB
SearchController.java 2KB
MessageService.java 2KB
LikeController.java 2KB
CommentService.java 2KB
FollowController.java 2KB
WebMvcConfig.java 2KB
Message.java 2KB
DiscussPostService.java 2KB
Comment.java 2KB
ExceptionAdvice.java 2KB
CommunityUtil.java 2KB
AlphaInterceptor.java 1KB
MessageMapper.java 1KB
KafkaTests.java 1KB
Page.java 1KB
DiscussPost.java 1KB
CommunityConstant.java 1KB
MailClient.java 1KB
LoginRequiredInterceptor.java 1KB
DataController.java 1KB
MessageInterceptor.java 1KB
KaptchaConfig.java 1KB
MailTests.java 1KB
RedisConfig.java 1KB
DataInterceptor.java 1KB
Event.java 1KB
LoginTicketMapper.java 1KB
TransactionTest.java 759B
LoggerTests.java 750B
SensitiveTests.java 728B
DiscussPostMapper.java 714B
CookieUtil.java 671B
EventProducer.java 617B
CommunityApplication.java 592B
User.java 531B
HostHolder.java 514B
UserMapper.java 445B
CommentMapper.java 422B
AlphaConfig.java 393B
LoginTicket.java 390B
DiscussPostRepository.java 377B
LoginRequired.java 362B
AlphaDaoMybatisImpl.java 338B
AlphaDaoHibernateImpl.java 296B
TestInterface.java 168B
共 122 条
- 1
- 2
资源评论
- 还有太多遗憾2024-03-14发现没有数据库和使用文档
程序员柳
- 粉丝: 6097
- 资源: 1195
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功