博客项目- SSM 实现
Posted 牧..
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了博客项目- SSM 实现相关的知识,希望对你有一定的参考价值。
文章目录
博客系统
前言 : 本文主要 是通过 ssm 搭配之前的 博客系统页面, 来完成一个小项目 .
1. 创建项目
使用到的技术 :
- 后端 : Spring Boot + Spring MVC + MyBatis + 拦截器 / 统一异常处理 + 统一数据返回 (Spring AOP)
- 前端 : html + CSS + javascript + jquery
2. 数据库设计
通过我们需要实现的功能 ,能够知道 需要两张表 , 第一张表 用户表 ,用来完成登录 注册 注销等功能 , 第二张表 用来存储 博客 , 查看博客等 .
1. 创建 用户列表
-- 如果存在 这个数据库就删除
drop
database if exits mywebsite;
-- 创建数据库
create
database mywebsite;
-- 选中数据库
use
mywebsite
-- 创建用户表
create table user
(
-- 系统分配
id int primary key auto_increment,
-- 必填
username varchar(255) not null,
password varchar(255) not null,
-- 非必填
qq varchar(255) default '',
address varchar(255) default '',
crateTime datetime default now(),
sex varchar(2) default '男',
-- url 用来存放 用户 头像 图片 如果用户没有上传就使用默认的 .
url varchar(1024) default '阳台.png'
);
2. 创建 blog 表
create table blog
(
blogId int primary key auto_increment,
title varchar(1024) not null,
-- 这里 一篇博客的内容可能非常多 使用 varchar可能不够 ,这里就是用 mediumtext
content mediumtext,
-- 用户 id
userid int,
-- 发布时间
postTime datetime default now(),
-- 类型
type varchar(255) not null,
);
表创建好了 ,下面就可以完成一些 准备工作 ,比如 配置好环境 , 写好 拦截器 ,统一数据格式 等 .
这里统一数据格式 可以写一个类 , 通过这个类来返回 或者 通过 @ControllerAdvice + ResponseBodyAdvice 来完成 , 这里我会使用 写一个类来返回信息 .
3. 前置任务
这里先来完成 拦截器 , 统一异常处理 , 统一数据格式 .
application.yml
# 配置当前运行的环境 (配置文件)
# spring > profiles > active
spring:
profiles:
active: dev # 使用开发环境的配置文件
# 配置 mybatis xml 保存路径
mybatis:
mapper-locations: classpath:mybatis/**Mapper.xml
# 在公共 yml 文件 来 配置 mybatis 的保存路径
application-dev.yml
# 开发环境的配置文件
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/mywebsite?characterEncoding=utf8
username: root
password: 1234
driver-class-name: com.mysql.cj.jdbc.Driver # 在 8.0 之前 是没有点 jc的 -> com.mysql.jdbc.Driver
# 设置日志级别
logging:
level:
com:
example:
usermanager: debug
# 对具体类机型日志级别设定
# 开启 MyBatis SQL 打印
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
3.1 拦截器
这里我们实现拦截器 主要有两部 : 1. 自定义拦截器 , 2. 给拦截器设置规则 (那些 需要拦截 , 那些不需要拦截)
附上代码 :
AppConfig 类
package com.example.usermanager.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 系统配置文件
*/
@Configuration
public class AppConfig implements WebMvcConfigurer
// 注入拦截器
@Autowired
private LoginIntercept loginIntercept;
@Override
public void addInterceptors(InterceptorRegistry registry)
registry.addInterceptor(loginIntercept).
addPathPatterns("/**")
.excludePathPatterns("/user/login")
.excludePathPatterns("/insert")
.excludePathPatterns("/css/**")
.excludePathPatterns("/fonts/**")
.excludePathPatterns("/images/**")
.excludePathPatterns("/js/**")
.excludePathPatterns("/login.html");
LoginIntercept
package com.example.blog_ssm.config;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* 自定义拦截器
*/
@Component
public class LoginIntercept implements HandlerInterceptor
/**
* true 表示已经登录 ,会继续访问目标方法
* false 表示未登录 , 跳转到登录页面
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
// false : 如果 没有 session 也不会创建
HttpSession session = request.getSession(false);
if (session != null && session.getAttribute("user") != null)
// 表示登录成功
return true;
// 403 当前你没有资格访问
response.setStatus(403);
// 重定向
response.sendRedirect("/login.html");
return false;
拦截器 弄好了 , 我们可以看看效果 :
xml 配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.blog_ssm.mapper.UserMapper">
</mapper>
3.2 统一数据格式
1. 创建一个类用来 统一 数据格式
附上代码 :
package com.example.blog_ssm.util;
import lombok.Data;
/**
* 用来统一数据格式
*
* @param <T>
*/
@Data
public class ResponseBodyMessage<T>
// 1. 状态码
private Integer status;
// 2. 信息描述
private String message;
// 3. 数据
private T data;
public ResponseBodyMessage(Integer status, String message, T data)
this.status = status;
this.message = message;
this.data = data;
2. 使用注解
3.3 创建一个 Constant
之前我们写拦截器的使用 ,通过 session 中的key 获取 user 对象时 ,写了一个 “user” , 这里可以使用一个类 ,在类里面写一个 常量 ,然后 只需要通过这个 来获取 user 即可 。
3.4 统一异常处理
代码 :
package com.example.blog_ssm.config;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.HashMap;
/**
* 统一异常的拦截处理类
*/
@RestControllerAdvice
// 使用 @ControllerAdvice 需要再加一个注解 @ResponseBody (返回一个非静态页面)
public class MyExceptionAdvice
@ExceptionHandler(Exception.class)
public Object exceptionAdvice(Exception e)
HashMap<String, Object> result = new HashMap<>();
result.put("status", -1);
result.put("message", "程序异常 : " + e.getMessage());
result.put("data", "");
return result;
3.5 密码加密
在 util 包内 创建 PasswordUtil 类
package com.example.blog_ssm.util;
import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.SecureUtil;
import org.springframework.util.StringUtils;
/**
* 密码工具类
*/
public class PasswordUtil
/**
* 1. 加密 (加盐)
*/
public String encrypt(String password)
// 密码 : 随机盐值 + 密码
String salt = IdUtil.simpleUUID();
String finalPassword = SecureUtil.md5(salt + password);
return salt + "$" + finalPassword;
/**
* 解密
*
* @param password 要验证的密码 (未加密)
* @return 数据库中的加了盐值的密码
*/
public boolean decrypt(String password, String securePassword)
boolean result = false;
if (StringUtils.hasLength(password) && StringUtils.hasLength(securePassword))
// 注意 : $ 是特殊字符 , 使用 split 分割时 需要转移
if (securePassword.length() == 65 && securePassword.contains("$"))
// 随机盐值 为 32 , md5 加密的 密码 32 加上 $ 1字符 总共 65 字符
String[] securePasswordArr = securePassword.split("\\\\$");
// 盐值
String salt = securePasswordArr[0];
// 根据盐值 加密的密码
String finalPassword = securePasswordArr[1];
// 根据盐值 对新的密码进行加密
password = SecureUtil.md5(salt + password);
// 进行对比
if (finalPassword.equals(password))
result = true;
return result;
将 工具类 交给 spring 管理 ,后面使用 只需要注入即可 .
到此我们就完成了前置任务, 下面来写我们的功能
4. 功能实现
4.1 登录功能
约定一下 : 请求和响应
请求 :
[
post, (登录一般使用 post)
/user/login
data:
username : "张三",
password :"1234"
]
响应 :
[
"status" : 1 / -1 (1 表示成功 , -1 表示失败) .
"message" : "登录成功" / "登录失败",
"data" : true / false
]
图一 :
图二 :
此时 后端就完成了 下面就可以来写前端了 :
图一 :
图二 :
代码 :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录页面</title>
<link rel="stylesheet" href="./css/common.css">
<link rel="stylesheet" href="./css/login.css">
<script src="./js/jquery.js"></script>
</head>
<body>
<!-- 导航栏 -->
<div class="nav">
<img src="./imgs/阳台.png">
<span class="title">我的博客系统</span>
<!-- 这个标签仅仅用于占位 ,把下面几个a 标签挤到右边-->
<div class="spacer"></div>
<a href="#">主页</a>
<a href="#">写博客</a>
</div>
<!--
正文部分
这个 login-container 是贯穿整个页面的容器
-->
<div class="login-container">
<!-- 垂直水平居中的登录对话框 -->
<div class="login-dialog">
<h3>登录</h3>
<div class="row">
<span>用户名</span>
<input type="text" id="username" placeholder="输入用户名">
</div>
<div class="row">
<span>密码</span>
<input type="password" id="password" placeholder="输入密码">
</div>
<div class="row">
<button id="submit">提交</button>
</div>
<div class="row">
<a id="insert" href = "add.html">
注册
</a>
</div>
<div class="a">没有账户? 点击上面进行注册</div>
</div>
</div>
<script>
// 通过 id 选中输入框 ,
let username = document.querySelector("#username");
// 通过 id 选中密码框
let password = document.querySelector("#password");
let submit = document.querySelector("#submit");
// 点击按钮后触发
submit.onclick = function ()
// 1. 判断 username or password
if (jQuery.trim(username.value) === '')
alert("请先输入用户名");
if (jQuery.trim(password.value) === '')
alert("请先输入密码")
// 此时 用户 和密码 都有了 ,发送 请求
$.ajax(
url: "/user/login",
type: "POST",
data:
"username": username.value,
https://v.qq.com/x/page/t07601n0cf2.html
或者也可以来这里观看整体的视频教程目录:http://edu.51cto.com/course/14736.html?source=so
在开发完成整个系统之后,不得不说自己对spring框架、mybatis框架的体系有了更为深入的认识,对于ssm整合的企业级java应用也有了更深入的理解!
此系统适合于具备了一定java基础以及spring,springmvc跟mybatis核心框架的基础要点的童鞋,系统将更深入的基于SSM整合更多的第三方框架并实现一套完整的项目即:个人博客系统,其中第三方框架包括shiro,lucene,jsoup,druid等等,在开发过程中我也遵循了mvc三层开发模式,加入了代码重构、工具类封装等代码可复用的理念,能更好的提升个人开发企业级应用的能力以及更深入的掌握SSM项目的开发。
此项目对于SSM整合项目实战者、SSM初学者、职场萌新以及个人博客系统课程设计需求者、毕业设计等等均可作为参考!
下面是系统以及视频教程涉及到的目录:
一:系统整体功能介绍
1.1 系统整体功能演示
1.2 基于SSM核心框架搭建系统整体架构
1.3 基于MVC开发模式构建项目目录结构
1.4 系统前后端开发流程介绍
1.5 源码数据库导入以及实战过程演示分享
二:系统整体业务模块开发
2.1 整合Shiro实现登录安全认证一
2.2 整合Shiro实现登录安全认证二
2.3 博客类型模块-基本信息管理
2.4 相关工具类开发介绍
2.5 博客模块-整合ueditor实现写博客功能
2.6 博客模块-ueditor中图片的上传存储实战
2.7 博客模块-整合lucene实战博客索引的创建
2.8 博客模块-基本信息管理一
2.9 博客模块-基本信息管理二
2.10 博客模块-整合lucene实战博客索引的管理
2.11 评论模块-评论基本信息管理实战
2.12 评论模块-评论审核实战
2.13 博主信息模块-基本信息管理
2.14 博主信息模块-再谈图片等附件的上传实战
2.15 友情链接模块-基本信息管理实战
三:系统管理模块
3.1 修改密码-密码工具类开发
3.2 缓存刷新-刷新缓存实战之同步初始化
3.3 缓存刷新-刷新缓存实战之异步初始化
3.3 退出登录以及重登录实战
四:前端模块(10)
4.1 首页实战开发-页面布局介绍
4.2 首页实战开发-博客列表
4.3 首页实战开发-再谈分页工具类
4.4 首页实战开发-右侧分类栏目列表
4.5 博客详情以及评论列表
4.6 首页搜索-lucene全文搜索实战一
4.7 首页搜索-关键字搜索
4.8 通用下载功能实战
4.9 总结+eclipse如何快速定位查找请求方法以及页面
完整的视频教程链接地址在此:http://edu.51cto.com/course/14736.html?source=so
完整视频教程目录截图:
由于此系统是本人自己花精力重整、设计、开发出来的,故而视频教程以及源码数据库需要收取一定的费用(当做是自己这一个多月辛勤付出的回报吧!),欢迎诸位支持支持!如果有兴趣的童鞋可以加我个人QQ:1974544863 向我索取(详情可以进一步咨询,可以砍价出售哦!)
附注:其中介绍到的知识点也会在微信公众号分享出来哦,所以,诸位童鞋也阔以关注关注!即将要分享是RabbitMQ以及SpringBoot实战跟SpringBoot项目整合实战的系列博文哦!
以上是关于博客项目- SSM 实现的主要内容,如果未能解决你的问题,请参考以下文章
Java项目:医院人事管理系统(java+SSM+jsp+layui+Mysql)