本次项目,完全从 0 到 1,从创建项目开始手把手教程,源码地址:个人博客
基本功能:
前端:HTML + CSS + JS + Jquery
后端: Spring MVC + Spring Boot + Mybatis + Redis
数据库: MySQL
开发环境:Windows 10 、IDEA
项目构建工具: maven
创建完成是这样的:
在 resource 下面创建 application.yml
在 application.yml 中添加 mybatis 配置:
# 配置数据库的连接字符串
spring:datasource:url: jdbc:mysql://localhost:3306/mycnblog?characterEncoding=utf8username: rootpassword: 12345678driver-class-name: com.mysql.cj.jdbc.Driver
# 设置 Mybatis 的 xml 保存路径
mybatis:mapper-locations: classpath:mapper/**Mapper.xmlconfiguration: # 配置打印 MyBatis 执行的 SQLlog-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 配置打印 MyBatis 执行的 SQL
logging:level:com:example:demo: debug
在 resource 下面创建 mapper 包:
SQL:
-- 创建数据库
drop database if exists mycnblog;
create database mycnblog DEFAULT CHARACTER SET utf8mb4;-- 使用数据数据
use mycnblog;-- 创建表[用户表]
drop table if exists userinfo;
create table userinfo(id int primary key auto_increment,username varchar(100) not null UNIQUE,password varchar(64) not null,photo varchar(500) default '',createtime datetime default now(),updatetime datetime default now(),`state` int default 1
) default charset 'utf8mb4';-- 创建文章表
drop table if exists articleinfo;
create table articleinfo(id int primary key auto_increment,title varchar(100) not null,content text not null,createtime datetime default now(),updatetime datetime default now(),uid int not null,rcount int not null default 1,`state` int default 1
)default charset 'utf8mb4';-- 添加一个用户信息
INSERT INTO `mycnblog`.`userinfo` (`id`, `username`, `password`, `photo`, `createtime`, `updatetime`, `state`) VALUES
(1, 'admin', 'admin', '', '2021-12-06 17:10:48', '2021-12-06 17:10:48', 1);-- 文章添加测试数据
insert into articleinfo(title,content,uid)values('Java','Java正文',1);
实体层就直接实现了,就两个表对应的实体类
UserInfo:
package com.example.mycnblog.model;import lombok.Data;@Data
public class UserInfo {/*** 用户id*/private Integer id;/*** 用户名*/private String username;/*** 密码*/private String password;/*** 电话号码*/private String photo;/*** 创建时间*/private String createTime;/*** 修改时间*/private String updateTime;/*** 状态*/private Integer state;
}
ArticleInfo:
package com.example.mycnblog.model;import lombok.Data;@Data
public class ArticleInfo {/*** 文章id*/private Integer id;/*** 标题*/private String title;/*** 正文*/private String content;/*** 创建时间*/private String createTime;/*** 修改时间*/private String updateTime;/*** 发布文章的uid*/private Integer uid;/*** 访问量*/private Integer rcount;/*** 状态*/private Integer state;
}
控制层,具体内容等功能实现的时候再来完善
UserController:
package com.example.mycnblog.controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** 用户控制器*/
@RestController
@RequestMapping("/user")
public class UserController {}
ArticleController:
package com.example.mycnblog.controller;import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** 文章控制器*/
@RestController
@RequestMapping("/art")
public class ArticleController {}
服务层,具体内容之后完善
UserService:
package com.example.mycnblog.service;import org.springframework.stereotype.Service;/*** 用户表的服务层*/
@Service
public class UserService {}
ArticleService:
package com.example.mycnblog.service;import org.springframework.stereotype.Service;/*** 文章表的服务层*/
@Service
public class ArticleService {}
持久层,具体内容之后完善
UserMapper:
package com.example.mycnblog.mapper;import org.apache.ibatis.annotations.Mapper;/*** 用户表的 mapper*/
@Mapper
public interface UserMapper {}
ArticleMapper:
package com.example.mycnblog.mapper;import org.apache.ibatis.annotations.Mapper;/*** 文章表的 mapper*/
@Mapper
public interface ArticleMapper {}
UserMapper.xml:
ArticleMapper.xml:
工具层,主要是一些统一处理(返回的数据类型,异常等等)
AjaxResult:
package com.example.mycnblog.common;import java.util.HashMap;/*** 自定义的统一返回对象*/
public class AjaxResult {/*** 业务执行成功时,返回的数据格式** @param data* @return*/public static HashMap success(Object data) {HashMap result = new HashMap<>();result.put("code", 200);result.put("msg", "");result.put("data", data);return result;}/*** 业务执行成功时,返回的数据格式** @param msg* @param data* @return*/public static HashMap success(String msg, Object data) {HashMap result = new HashMap<>();result.put("code", 200);result.put("msg", msg);result.put("data", data);return result;}/*** 业务执行失败时,返回的数据格式** @param code* @param msg* @return*/public static HashMap fail(int code, String msg) {HashMap result = new HashMap<>();result.put("code", code);result.put("msg", msg);result.put("data", "");return result;}/*** 业务执行失败时,返回的数据格式** @param code* @param msg* @param data* @return*/public static HashMap fail(int code, String msg, Object data) {HashMap result = new HashMap<>();result.put("code", code);result.put("msg", msg);result.put("data", data);return result;}
}
这个地方在做统一返回的时候需要注意一下 String 类的情况
ResponseAdvice:
package com.example.mycnblog.common;import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;import java.util.HashMap;/*** 统一数据返回封装*/
@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {@Overridepublic boolean supports(MethodParameter returnType, Class converterType) {return true;}@SneakyThrows@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {if(body instanceof HashMap){ // 本身已经是封装好的对象return body;}if (body instanceof String) { // 返回类型是 string 类ObjectMapper objectMapper = new ObjectMapper();return objectMapper.writeValueAsString(AjaxResult.success(body));}return AjaxResult.success(body);}
}
这里还可以具体到各个异常
ExceptionAdvice:
package com.example.mycnblog.common;import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;/*** 异常类的统一处理*/
@ControllerAdvice
@ResponseBody
public class ExceptionAdvice {@ExceptionHandler(Exception.class)public Object exceptionAdvice(Exception e) {return AjaxResult.fail(-1, e.getMessage());}
}
直接将我们提前准备好的前端页面直接复制粘贴到 /resource/static 目录下:
reg.html:
注册页面
注册
用户名密码确认密码
注册功能,后端只需要将用户名和密码保存到数据库即可,就是一个简单的 insert。
UserMapper:->add
package com.example.mycnblog.mapper;import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;/*** 用户表的 mapper*/
@Mapper
public interface UserMapper {/*** 用户注册* @param username* @param password* @return*/public int add(@Param("username") String username,@Param("password") String password);}
UserMapper.xml:->add
insert into userinfo(username, password)values (#{username}, #{password})
UserService:->add
package com.example.mycnblog.service;import com.example.mycnblog.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;/*** 用户表的服务层*/
@Service
public class UserService {@Autowiredprivate UserMapper userMapper;/*** 用户注册* @param username* @param password* @return*/public int add(String username, String password) {return userMapper.add(username, password);}}
UserController:->reg
package com.example.mycnblog.controller;import com.example.mycnblog.common.AjaxResult;
import com.example.mycnblog.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** 用户控制器*/
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;/*** 用户注册* @param username* @param password* @return*/@RequestMapping("/reg")public Object reg(String username, String password) {// 1.非空效验if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {return AjaxResult.fail(-1, "非法的参数请求!");}// 2.进行添加操作int result = userService.add(username, password);if (result == 1) {return AjaxResult.success("注册成功!", 1);} else {return AjaxResult.fail(-1, "数据库添加出错!");}}
}
页面:
输入 -> 张三 123456
点击提交
日志信息:
数据库信息:
login.html:
登陆页面
登陆
用户名密码
登录功能的基础:就是从数据库中查找用户名和密码,与用户输入是否匹配
UserMapper:->login
package com.example.mycnblog.mapper;import com.example.mycnblog.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;/*** 用户表的 mapper*/
@Mapper
public interface UserMapper {/*** 用户注册* @param username* @param password* @return*/public int add(@Param("username") String username,@Param("password") String password);/*** 用户登录* @param username* @param password* @return*/public UserInfo login(@Param("username") String username,@Param("password") String password);
}
UserMapper.xml:->login
insert into userinfo(username, password)values (#{username}, #{password})
UserService:->login
package com.example.mycnblog.service;import com.example.mycnblog.mapper.UserMapper;
import com.example.mycnblog.model.UserInfo;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;/*** 用户表的服务层*/
@Service
public class UserService {@Autowiredprivate UserMapper userMapper;/*** 用户注册* @param username* @param password* @return*/public int add(String username, String password) {return userMapper.add(username, password);}/*** 用户登录* @param username* @param password* @return*/public UserInfo login(String username, String password) {return userMapper.login(username, password);}}
UserController:->login
package com.example.mycnblog.controller;import com.example.mycnblog.common.AjaxResult;
import com.example.mycnblog.model.UserInfo;
import com.example.mycnblog.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** 用户控制器*/
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;/*** 用户注册* @param username* @param password* @return*/@RequestMapping("/reg")public Object reg(String username, String password) {// 1.非空效验if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {return AjaxResult.fail(-1, "非法的参数请求!");}// 2.进行添加操作int result = userService.add(username, password);if (result == 1) {return AjaxResult.success("注册成功!", 1);} else {return AjaxResult.fail(-1, "数据库添加出错!");}}/*** 用户登录* @param username* @param password* @return*/@RequestMapping("/login")public int login(String username, String password) {// 1.非空效验if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {// 参数有误return 0;}// 2.进行查找操作UserInfo userInfo = userService.login(username, password);if (userInfo == null || userInfo.getId() <= 0) { // userinfo 无效// 用户名或密码错误return -1;} else {// 用户名和密码正确return 1;}}
}
页面:
输入 -> 张三 123456
点击提交
日志信息:
- 存储session:需要用一个常量,来存放 session 的 key,我们之后也可以通过这个 key 拿到当前登录用户的信息;我们在存储 session 时,同样也是把 value 存放到对应的 key 中。
- 拦截器:具体可以看看我之前的博客——SpringBoot 统一功能处理
在 common 包下添加一个 Constant 类,用来存放常量
Constant:
package com.example.mycnblog.common;/*** 当前项目中的所有常量*/
public class Constant {// 登录信息存储到 session 中的 keypublic static final String SESSION_USERINFO_KEY = "session_userinfo_key";
}
UserController:->login
package com.example.mycnblog.controller;import com.example.mycnblog.common.AjaxResult;
import com.example.mycnblog.common.Constant;
import com.example.mycnblog.model.UserInfo;
import com.example.mycnblog.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;/*** 用户控制器*/
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;/*** 用户注册** @param username* @param password* @return*/@RequestMapping("/reg")public Object reg(String username, String password) {// 1.非空效验if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {return AjaxResult.fail(-1, "非法的参数请求!");}// 2.进行添加操作int result = userService.add(username, password);if (result == 1) {return AjaxResult.success("注册成功!", 1);} else {return AjaxResult.fail(-1, "数据库添加出错!");}}/*** 用户登录** @param username* @param password* @return 如果用户名和密码都正确,返回1;如果用户名或密码为空/不正确,返回非1*/@RequestMapping("/login")public int login(HttpServletRequest request, String username, String password) {// 1.非空效验if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {// 参数有误return 0;}// 2.进行查找操作UserInfo userInfo = userService.login(username, password);if (userInfo == null || userInfo.getId() <= 0) { // userinfo 无效// 用户名或密码错误return -1;} else {// 用户名和密码正确// 将 userinfo 保存到 session 中HttpSession session = request.getSession();session.setAttribute(Constant.SESSION_USERINFO_KEY, userInfo);return 1;}}
}
在 common 包下添加一个 LoginInterceptor 类,自定义拦截器;以及一个 AppConfig 类,配置拦截器。
LoginInterceptor:
package com.example.mycnblog.common;import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;/*** 自定义拦截器*/
@Component
public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// session 得到用户信息【如果从 session 中得到了 userinfo 对象,说明用户已经登录了,如果没得到,说明未登录】HttpSession session = request.getSession(false);if (session != null && session.getAttribute(Constant.SESSION_USERINFO_KEY) != null) {// 当前用户已经登录了return true;}response.setStatus(401);return false;}
}
AppConfig:->addInterceptors
package com.example.mycnblog.common;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import java.util.ArrayList;
import java.util.List;/*** 配置拦截器*/
@Configuration
public class AppConfig implements WebMvcConfigurer {// 不拦截的 url 集合List excludes = new ArrayList(){{add("/**/*.html");add("/js/**"); // 放行 static/js 下的所有文件add("/editor.md/**"); // 放行 static/editor.md 下的所有文件add("/css/**"); // 放行 static/css 下的所有文件add("/img/**"); // 放行 static/img 下的所有文件add("/user/reg"); // 放行注册接口add("/user/login"); // 放行登录接口}};@Autowiredprivate LoginInterceptor loginInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 配置拦截器InterceptorRegistration registration =registry.addInterceptor(loginInterceptor);registration.addPathPatterns("/**"); // 拦截所有请求registration.excludePathPatterns(excludes); // 排除不拦截的 url}
}
myblog_list.html:
博客列表
退出登录:这个主要就是把 session 中的信息删除。
UserController:->logout
package com.example.mycnblog.controller;import com.example.mycnblog.common.AjaxResult;
import com.example.mycnblog.common.Constant;
import com.example.mycnblog.model.UserInfo;
import com.example.mycnblog.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;/*** 用户控制器*/
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;/*** 用户注册** @param username* @param password* @return*/@RequestMapping("/reg")public Object reg(String username, String password) {// 1.非空效验if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {return AjaxResult.fail(-1, "非法的参数请求!");}// 2.进行添加操作int result = userService.add(username, password);if (result == 1) {return AjaxResult.success("注册成功!", 1);} else {return AjaxResult.fail(-1, "数据库添加出错!");}}/*** 用户登录** @param username* @param password* @return 如果用户名和密码都正确,返回1;如果用户名或密码为空/不正确,返回非1*/@RequestMapping("/login")public int login(HttpServletRequest request, String username, String password) {// 1.非空效验if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {// 参数有误return 0;}// 2.进行查找操作UserInfo userInfo = userService.login(username, password);if (userInfo == null || userInfo.getId() <= 0) { // userinfo 无效// 用户名或密码错误return -1;} else {// 用户名和密码正确// 将 userinfo 保存到 session 中HttpSession session = request.getSession();session.setAttribute(Constant.SESSION_USERINFO_KEY, userInfo);return 1;}}/*** 退出登录* @param request* @return*/@RequestMapping("/logout")public boolean logout(HttpServletRequest request) {HttpSession session = request.getSession(false);if (session != null &&session.getAttribute(Constant.SESSION_USERINFO_KEY) != null) {// 移除 session 中当前登录的用户session.removeAttribute(Constant.SESSION_USERINFO_KEY);}return true;}
}
成功登录后:
点击退出登录:
点击确定 -> 来到登录界面:
在未登录的情况下,直接进入博客列表,点击退出登录 -> 确定:
就会来到登录界面:
个人博客展示:这个就是在 session 中拿到用户信息,然后根据用户的 id,来查询文章。
ArticleMapper:getMyList
package com.example.mycnblog.mapper;import com.example.mycnblog.model.ArticleInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;import java.util.List;/*** 文章表的 mapper*/
@Mapper
public interface ArticleMapper {/*** 根据用户id(uid)查询所有文章* @param uid* @return*/public List getMyList(@Param("uid") Integer uid);}
ArticleMapper.xml:getMyList
ArticleServic:->getMyList
package com.example.mycnblog.service;import com.example.mycnblog.mapper.ArticleMapper;
import com.example.mycnblog.model.ArticleInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;/*** 文章表的服务层*/
@Service
public class ArticleService {@Autowiredprivate ArticleMapper articleMapper;/*** 查询用户的所有文章* @param uid* @return*/public List getMyList(Integer uid){return articleMapper.getMyList(uid);}}
ArticleController:->myList
package com.example.mycnblog.controller;import com.example.mycnblog.common.Constant;
import com.example.mycnblog.model.ArticleInfo;
import com.example.mycnblog.model.UserInfo;
import com.example.mycnblog.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.List;/*** 文章控制器*/
@RestController
@RequestMapping("/art")
public class ArticleController {@Autowiredprivate ArticleService articleService;/*** 查询用户的所有文章* @param request* @return*/@RequestMapping("/mylist")public List myList(HttpServletRequest request) {HttpSession session = request.getSession(false);if (session != null &&session.getAttribute(Constant.SESSION_USERINFO_KEY) != null) {UserInfo userInfo = (UserInfo) session.getAttribute(Constant.SESSION_USERINFO_KEY);return articleService.getMyList(userInfo.getId());}return null;}}
页面:
日志信息:
数据库信息:
个人信息:这个跟博客展示其实差不多,直接在 session 中就可以拿到信息。
UserController:->myInfo
package com.example.mycnblog.controller;import com.example.mycnblog.common.AjaxResult;
import com.example.mycnblog.common.Constant;
import com.example.mycnblog.model.UserInfo;
import com.example.mycnblog.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;/*** 用户控制器*/
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;/*** 用户注册** @param username* @param password* @return*/@RequestMapping("/reg")public Object reg(String username, String password) {// 1.非空效验if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {return AjaxResult.fail(-1, "非法的参数请求!");}// 2.进行添加操作int result = userService.add(username, password);if (result == 1) {return AjaxResult.success("注册成功!", 1);} else {return AjaxResult.fail(-1, "数据库添加出错!");}}/*** 用户登录** @param username* @param password* @return 如果用户名和密码都正确,返回1;如果用户名或密码为空/不正确,返回非1*/@RequestMapping("/login")public int login(HttpServletRequest request, String username, String password) {// 1.非空效验if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {// 参数有误return 0;}// 2.进行查找操作UserInfo userInfo = userService.login(username, password);if (userInfo == null || userInfo.getId() <= 0) { // userinfo 无效// 用户名或密码错误return -1;} else {// 用户名和密码正确// 将 userinfo 保存到 session 中HttpSession session = request.getSession();session.setAttribute(Constant.SESSION_USERINFO_KEY, userInfo);return 1;}}/*** 退出登录** @param request* @return*/@RequestMapping("/logout")public boolean logout(HttpServletRequest request) {HttpSession session = request.getSession(false);if (session != null &&session.getAttribute(Constant.SESSION_USERINFO_KEY) != null) {// 移除 session 中当前登录的用户session.removeAttribute(Constant.SESSION_USERINFO_KEY);}return true;}/*** 获取个人信息* @param request* @return*/@RequestMapping("/myinfo")public UserInfo myInfo(HttpServletRequest request) {HttpSession session = request.getSession(false);if (session != null &&session.getAttribute(Constant.SESSION_USERINFO_KEY) != null) {return (UserInfo) session.getAttribute(Constant.SESSION_USERINFO_KEY);}return null;}
}
这里的 tools.js 是因为这个功能在很多地方都用到了,所以封装成 js 工具类。
tools.js:
// 获取当前 url 中某个参数的方法
function getURLParam(key) {var params = location.search;if (params.indexOf("?") >= 0) {params = params.substring(params.indexOf("?") + 1);var paramArr = params.split('&');for (var i = 0; i < paramArr.length; i++) {var namevalues = paramArr[i].split("=");if (namevalues[0] == key) {return namevalues[1];}}} else {return "";}
}
blog_content.html:
博客正文
标题
访问量:
文章展示:通过文章 id 查询文章的详细信息,值得注意的就是后面我们在全部博客列表中,也会用到这个功能,所以我们需要在拦截器中放行该接口。
ArticleMapper:->getDetil
package com.example.mycnblog.mapper;import com.example.mycnblog.model.ArticleInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;import java.util.List;/*** 文章表的 mapper*/
@Mapper
public interface ArticleMapper {/*** 根据用户id(uid)查询所有文章* @param uid* @return*/public List getMyList(@Param("uid") Integer uid);/*** 根据文章id(id)获取文章的详情信息* @param aid* @return*/public ArticleInfo getDetail(@Param("aid") Integer aid);
}
ArticleMapper.xml:->getDetil
ArticleService:->getDetil
package com.example.mycnblog.service;import com.example.mycnblog.mapper.ArticleMapper;
import com.example.mycnblog.model.ArticleInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;/*** 文章表的服务层*/
@Service
public class ArticleService {@Autowiredprivate ArticleMapper articleMapper;/*** 查询用户的所有文章** @param uid* @return*/public List getMyList(Integer uid) {return articleMapper.getMyList(uid);}/*** 获取文章的详情信息** @param aid* @return*/public ArticleInfo getDetil(Integer aid) {return articleMapper.getDetail(aid);}
}
ArticleController:->getDetil
package com.example.mycnblog.controller;import com.example.mycnblog.common.AjaxResult;
import com.example.mycnblog.common.Constant;
import com.example.mycnblog.model.ArticleInfo;
import com.example.mycnblog.model.UserInfo;
import com.example.mycnblog.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.List;/*** 文章控制器*/
@RestController
@RequestMapping("/art")
public class ArticleController {@Autowiredprivate ArticleService articleService;/*** 查询用户的所有文章** @param request* @return*/@RequestMapping("/mylist")public List myList(HttpServletRequest request) {HttpSession session = request.getSession(false);if (session != null &&session.getAttribute(Constant.SESSION_USERINFO_KEY) != null) {UserInfo userInfo = (UserInfo) session.getAttribute(Constant.SESSION_USERINFO_KEY);return articleService.getMyList(userInfo.getId());}return null;}/*** 获取文章的详情信息** @param aid* @return*/@RequestMapping("/detail")public Object getDetil(Integer aid) {if (aid != null && aid > 0) {return AjaxResult.success(articleService.getDetil(aid));}return AjaxResult.fail(-1, "查询失败");}
}
涉及到之后,我们可能在所有文章列表中也需要,查询文章详情,所以直接把这个接口放行。
AppConfig:->放行文章详情接口
package com.example.mycnblog.common;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import java.util.ArrayList;
import java.util.List;/*** 配置拦截器*/
@Configuration
public class AppConfig implements WebMvcConfigurer {// 不拦截的 url 集合List excludes = new ArrayList(){{add("/**/*.html");add("/js/**"); // 放行 static/js 下的所有文件add("/editor.md/**"); // 放行 static/editor.md 下的所有文件add("/css/**"); // 放行 static/css 下的所有文件add("/img/**"); // 放行 static/img 下的所有文件add("/user/reg"); // 放行注册接口add("/user/login"); // 放行登录接口add("/art/detail"); // 放行文章详情接口}};@Autowiredprivate LoginInterceptor loginInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 配置拦截器InterceptorRegistration registration =registry.addInterceptor(loginInterceptor);registration.addPathPatterns("/**"); // 拦截所有请求registration.excludePathPatterns(excludes); // 排除不拦截的 url}
}
进入个人博客页面,点击查看详情:
就得到了文章的详情内容:
作者信息:在文章展示的同时,前端可以获取到文章的 uid,然后后端就可以通过这个 uid 查询作者信息。
UserMapper:->myInfoByUid
package com.example.mycnblog.mapper;import com.example.mycnblog.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;/*** 用户表的 mapper*/
@Mapper
public interface UserMapper {/*** 用户注册* @param username* @param password* @return*/public int add(@Param("username") String username,@Param("password") String password);/*** 用户登录* @param username* @param password* @return*/public UserInfo login(@Param("username") String username,@Param("password") String password);/*** 通过用户 id 查询用户信息* @param uid* @return*/public UserInfo myInfoByUid(@Param("uid") Integer uid);
}
UserMapper.xml:->myInfoByUid
insert into userinfo(username, password)values (#{username}, #{password})
UserService:->myInfoByUid
package com.example.mycnblog.service;import com.example.mycnblog.mapper.UserMapper;
import com.example.mycnblog.model.UserInfo;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;/*** 用户表的服务层*/
@Service
public class UserService {@Autowiredprivate UserMapper userMapper;/*** 用户注册* @param username* @param password* @return*/public int add(String username, String password) {return userMapper.add(username, password);}/*** 用户登录* @param username* @param password* @return*/public UserInfo login(String username, String password) {return userMapper.login(username, password);}/*** 获取作者信息* @param uid* @return*/public UserInfo myInfoByUid(Integer uid){return userMapper.myInfoByUid(uid);}
}
UserController:->myInfoByUid
package com.example.mycnblog.controller;import com.example.mycnblog.common.AjaxResult;
import com.example.mycnblog.common.Constant;
import com.example.mycnblog.model.UserInfo;
import com.example.mycnblog.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;/*** 用户控制器*/
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;/*** 用户注册** @param username* @param password* @return*/@RequestMapping("/reg")public Object reg(String username, String password) {// 1.非空效验if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {return AjaxResult.fail(-1, "非法的参数请求!");}// 2.进行添加操作int result = userService.add(username, password);if (result == 1) {return AjaxResult.success("注册成功!", 1);} else {return AjaxResult.fail(-1, "数据库添加出错!");}}/*** 用户登录** @param username* @param password* @return 如果用户名和密码都正确,返回1;如果用户名或密码为空/不正确,返回非1*/@RequestMapping("/login")public int login(HttpServletRequest request, String username, String password) {// 1.非空效验if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {// 参数有误return 0;}// 2.进行查找操作UserInfo userInfo = userService.login(username, password);if (userInfo == null || userInfo.getId() <= 0) { // userinfo 无效// 用户名或密码错误return -1;} else {// 用户名和密码正确// 将 userinfo 保存到 session 中HttpSession session = request.getSession();session.setAttribute(Constant.SESSION_USERINFO_KEY, userInfo);return 1;}}/*** 退出登录** @param request* @return*/@RequestMapping("/logout")public boolean logout(HttpServletRequest request) {HttpSession session = request.getSession(false);if (session != null &&session.getAttribute(Constant.SESSION_USERINFO_KEY) != null) {// 移除 session 中当前登录的用户session.removeAttribute(Constant.SESSION_USERINFO_KEY);}return true;}/*** 获取个人信息** @param request* @return*/@RequestMapping("/myinfo")public UserInfo myInfo(HttpServletRequest request) {HttpSession session = request.getSession(false);if (session != null &&session.getAttribute(Constant.SESSION_USERINFO_KEY) != null) {return (UserInfo) session.getAttribute(Constant.SESSION_USERINFO_KEY);}return null;}/*** 获取作者信息* @param uid* @return*/@RequestMapping("/myinfobyuid")public UserInfo myInfoByUid(Integer uid) {if (uid != null && uid > 0) {return userService.myInfoByUid(uid);}return null;}
}
blog_update.html:
博客编辑
查询文章:这个就是通过文章 id 查询文章内容,这里的数据库和服务层可以用我们之前已经实现好的 getDetil;同时还有进行一次文章的归属人验证,这里就需要用到获取 session 信息,之前 myList 这个接口也用到了,所以我们就可以把它封装起来。
SessionUtil:->getLoginUser
package com.example.mycnblog.common;import com.example.mycnblog.model.UserInfo;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;public class SessionUtil {/*** 查询当前登录用户的 session 信息* @param request* @return*/public static UserInfo getLoginUser(HttpServletRequest request){HttpSession session = request.getSession(false);if (session != null &&session.getAttribute(Constant.SESSION_USERINFO_KEY) != null) {return (UserInfo) session.getAttribute(Constant.SESSION_USERINFO_KEY);}return null;}
}
ArticleController:->getDetailById
package com.example.mycnblog.controller;import com.example.mycnblog.common.AjaxResult;
import com.example.mycnblog.common.Constant;
import com.example.mycnblog.common.SessionUtil;
import com.example.mycnblog.model.ArticleInfo;
import com.example.mycnblog.model.UserInfo;
import com.example.mycnblog.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.List;/*** 文章控制器*/
@RestController
@RequestMapping("/art")
public class ArticleController {@Autowiredprivate ArticleService articleService;/*** 查询用户的所有文章** @param request* @return*/@RequestMapping("/mylist")public List myList(HttpServletRequest request) {UserInfo userInfo = SessionUtil.getLoginUser(request);if (userInfo != null) {return articleService.getMyList(userInfo.getId());}return null;}/*** 获取文章的详情信息** @param aid* @return*/@RequestMapping("/detail")public Object getDetil(Integer aid) {if (aid != null && aid > 0) {return AjaxResult.success(articleService.getDetil(aid));}return AjaxResult.fail(-1, "查询失败");}/*** 修改页面,查询文章** @param request* @param aid* @return*/@RequestMapping("/detailbyid")public Object getDetailById(HttpServletRequest request, Integer aid) {if (aid != null && aid > 0) {// 根据文章查询文章的详情ArticleInfo articleInfo = articleService.getDetil(aid);// 文章的归属人验证UserInfo userInfo = SessionUtil.getLoginUser(request);if (userInfo != null && articleInfo != null &&userInfo.getId() == articleInfo.getUid()) { // 文章归属人正确return AjaxResult.success(articleInfo);}}return AjaxResult.fail(-1, "查询失败");}
}
进入个人博客页面,点击修改:
就到了修改界面:
ArticleMapper:->update
package com.example.mycnblog.mapper;import com.example.mycnblog.model.ArticleInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;import java.util.List;/*** 文章表的 mapper*/
@Mapper
public interface ArticleMapper {/*** 根据用户id(uid)查询所有文章** @param uid* @return*/public List getMyList(@Param("uid") Integer uid);/*** 根据文章id(id)获取文章的详情信息** @param aid* @return*/public ArticleInfo getDetail(@Param("aid") Integer aid);/*** 根据文章id(id)和用户id(uid)修改文章的标题和内容** @param aid* @param uid* @param title* @param content* @return*/public int update(@Param("aid") Integer aid,@Param("uid") Integer uid,@Param("title") String title,@Param("content") String content);
}
ArticleMapper.xml:->update
update articleinfoset title=#{title},content=#{content}where id = #{aid}and uid = #{uid}
ArticleService:->update
package com.example.mycnblog.service;import com.example.mycnblog.mapper.ArticleMapper;
import com.example.mycnblog.model.ArticleInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;/*** 文章表的服务层*/
@Service
public class ArticleService {@Autowiredprivate ArticleMapper articleMapper;/*** 查询用户的所有文章** @param uid* @return*/public List getMyList(Integer uid) {return articleMapper.getMyList(uid);}/*** 获取文章的详情信息** @param aid* @return*/public ArticleInfo getDetil(Integer aid) {return articleMapper.getDetail(aid);}/*** 修改页面,修改文章* @param aid* @param uid* @param title* @param content* @return*/public int update(Integer aid, Integer uid, String title, String content) {return articleMapper.update(aid, uid, title, content);}
}
ArticleController:->update
package com.example.mycnblog.controller;import com.example.mycnblog.common.AjaxResult;
import com.example.mycnblog.common.Constant;
import com.example.mycnblog.common.SessionUtil;
import com.example.mycnblog.model.ArticleInfo;
import com.example.mycnblog.model.UserInfo;
import com.example.mycnblog.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.List;/*** 文章控制器*/
@RestController
@RequestMapping("/art")
public class ArticleController {@Autowiredprivate ArticleService articleService;/*** 查询用户的所有文章** @param request* @return*/@RequestMapping("/mylist")public List myList(HttpServletRequest request) {UserInfo userInfo = SessionUtil.getLoginUser(request);if (userInfo != null) {return articleService.getMyList(userInfo.getId());}return null;}/*** 获取文章的详情信息** @param aid* @return*/@RequestMapping("/detail")public Object getDetil(Integer aid) {if (aid != null && aid > 0) {return AjaxResult.success(articleService.getDetil(aid));}return AjaxResult.fail(-1, "查询失败");}/*** 修改页面,查询文章** @param request* @param aid* @return*/@RequestMapping("/detailbyid")public Object getDetailById(HttpServletRequest request, Integer aid) {if (aid != null && aid > 0) {// 根据文章查询文章的详情ArticleInfo articleInfo = articleService.getDetil(aid);// 文章的归属人验证UserInfo userInfo = SessionUtil.getLoginUser(request);if (userInfo != null && articleInfo != null &&userInfo.getId() == articleInfo.getUid()) { // 文章归属人正确return AjaxResult.success(articleInfo);}}return AjaxResult.fail(-1, "查询失败");}/*** 修改页面,修改文章* @param request* @param aid* @param title* @param content* @return*/@RequestMapping("/update")public int update(HttpServletRequest request, Integer aid, String title, String content) {// 非空校验if (aid == null || !StringUtils.hasLength(title) || !StringUtils.hasLength(content)) {// 参数有误return 0;}UserInfo userInfo = SessionUtil.getLoginUser(request);if (userInfo != null && userInfo.getId() > 0) {return articleService.update(aid, userInfo.getId(), title, content);}return 0;}
}
修改前数据库信息:
进入修改页面,做出修改,点击修改文章:
提示修改成功:
跳转至个人博客列表:
修改后数据库信息:
myblog_list.html:
博客列表
文章删除:这个其实很简单,对于后端来说,就是一个简单的通过文章 id 删除文章。
ArticleMapper:->delete
package com.example.mycnblog.mapper;import com.example.mycnblog.model.ArticleInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;import java.util.List;/*** 文章表的 mapper*/
@Mapper
public interface ArticleMapper {/*** 根据用户id(uid)查询所有文章** @param uid* @return*/public List getMyList(@Param("uid") Integer uid);/*** 根据文章id(id)获取文章的详情信息** @param aid* @return*/public ArticleInfo getDetail(@Param("aid") Integer aid);/*** 根据文章id(id)和用户id(uid)修改文章的标题和内容** @param aid* @param uid* @param title* @param content* @return*/public int update(@Param("aid") Integer aid,@Param("uid") Integer uid,@Param("title") String title,@Param("content") String content);/*** 根据文章id(id)删除文章** @param aid* @return*/public int delete(@Param("aid") Integer aid);
}
ArticleMapper.xml:->delete
update articleinfoset title=#{title},content=#{content}where id = #{aid}and uid = #{uid} deletefrom articleinfowhere id = #{aid}
ArticleService:->delete
package com.example.mycnblog.service;import com.example.mycnblog.mapper.ArticleMapper;
import com.example.mycnblog.model.ArticleInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import javax.servlet.http.HttpServletRequest;
import java.util.List;/*** 文章表的服务层*/
@Service
public class ArticleService {@Autowiredprivate ArticleMapper articleMapper;/*** 用户博客列表,查询用户的所有文章** @param uid* @return*/public List getMyList(Integer uid) {return articleMapper.getMyList(uid);}/*** 用户博客列表,获取文章的详情信息** @param aid* @return*/public ArticleInfo getDetil(Integer aid) {return articleMapper.getDetail(aid);}/*** 修改页面,修改文章** @param aid* @param uid* @param title* @param content* @return*/public int update(Integer aid, Integer uid, String title, String content) {return articleMapper.update(aid, uid, title, content);}/*** 用户博客列表,删除文章** @param aid* @return*/public int delete(Integer aid) {return articleMapper.delete(aid);}
}
ArticleController:->delete
package com.example.mycnblog.controller;import com.example.mycnblog.common.AjaxResult;
import com.example.mycnblog.common.Constant;
import com.example.mycnblog.common.SessionUtil;
import com.example.mycnblog.model.ArticleInfo;
import com.example.mycnblog.model.UserInfo;
import com.example.mycnblog.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.List;/*** 文章控制器*/
@RestController
@RequestMapping("/art")
public class ArticleController {@Autowiredprivate ArticleService articleService;/*** 查询用户的所有文章** @param request* @return*/@RequestMapping("/mylist")public List myList(HttpServletRequest request) {UserInfo userInfo = SessionUtil.getLoginUser(request);if (userInfo != null) {return articleService.getMyList(userInfo.getId());}return null;}/*** 获取文章的详情信息** @param aid* @return*/@RequestMapping("/detail")public Object getDetil(Integer aid) {if (aid != null && aid > 0) {return AjaxResult.success(articleService.getDetil(aid));}return AjaxResult.fail(-1, "查询失败");}/*** 修改页面,查询文章** @param request* @param aid* @return*/@RequestMapping("/detailbyid")public Object getDetailById(HttpServletRequest request, Integer aid) {if (aid != null && aid > 0) {// 根据文章查询文章的详情ArticleInfo articleInfo = articleService.getDetil(aid);// 文章的归属人验证UserInfo userInfo = SessionUtil.getLoginUser(request);if (userInfo != null && articleInfo != null &&userInfo.getId() == articleInfo.getUid()) { // 文章归属人正确return AjaxResult.success(articleInfo);}}return AjaxResult.fail(-1, "查询失败");}/*** 修改页面,修改文章** @param request* @param aid* @param title* @param content* @return*/@RequestMapping("/update")public int update(HttpServletRequest request, Integer aid, String title, String content) {// 非空校验if (aid == null || !StringUtils.hasLength(title) || !StringUtils.hasLength(content)) {// 参数有误return 0;}UserInfo userInfo = SessionUtil.getLoginUser(request);if (userInfo != null && userInfo.getId() > 0) {return articleService.update(aid, userInfo.getId(), title, content);}return 0;}/*** 博客列表,删除文章* * @param request* @param aid* @return*/@RequestMapping("/delete")public int delete(HttpServletRequest request, Integer aid) {// 非空校验if (aid == null && aid <= 0) {// 参数有误return 0;}UserInfo userInfo = SessionUtil.getLoginUser(request);if (userInfo != null) { // 当前已登录return articleService.delete(aid);}return 0;}
}
删除前数据库信息:
登录后,进入博客列表:
点击删除:
确定删除:
删除后数据库信息:
blog_edit.html:
博客编辑
发布文章:这个它其实和修改文章差不多,只是不需要获取文章的 id了,这个在发布时,数据库会自己自增 id。
ArticleMapper:->add
package com.example.mycnblog.mapper;import com.example.mycnblog.model.ArticleInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;import java.util.List;/*** 文章表的 mapper*/
@Mapper
public interface ArticleMapper {/*** 根据用户id(uid)查询所有文章** @param uid* @return*/public List getMyList(@Param("uid") Integer uid);/*** 根据文章id(id)获取文章的详情信息** @param aid* @return*/public ArticleInfo getDetail(@Param("aid") Integer aid);/*** 根据文章id(id)和用户id(uid)修改文章的标题和内容** @param aid* @param uid* @param title* @param content* @return*/public int update(@Param("aid") Integer aid,@Param("uid") Integer uid,@Param("title") String title,@Param("content") String content);/*** 根据文章id(id)删除文章** @param aid* @return*/public int delete(@Param("aid") Integer aid);/*** 添加文章(uid,文章标题,文章内容)** @param uid* @param title* @param content* @return*/public int add(@Param("uid") Integer uid,@Param("title") String title,@Param("content") String content);
}
ArticleMapper.xml:->add
update articleinfoset title=#{title},content=#{content}where id = #{aid}and uid = #{uid} deletefrom articleinfowhere id = #{aid} insert into articleinfo(title, content, uid)values (#{title}, #{content}, #{uid});
ArticleService:->add
package com.example.mycnblog.service;import com.example.mycnblog.mapper.ArticleMapper;
import com.example.mycnblog.model.ArticleInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import javax.servlet.http.HttpServletRequest;
import java.util.List;/*** 文章表的服务层*/
@Service
public class ArticleService {@Autowiredprivate ArticleMapper articleMapper;/*** 用户博客列表,查询用户的所有文章** @param uid* @return*/public List getMyList(Integer uid) {return articleMapper.getMyList(uid);}/*** 用户博客列表,获取文章的详情信息** @param aid* @return*/public ArticleInfo getDetil(Integer aid) {return articleMapper.getDetail(aid);}/*** 修改页面,修改文章** @param aid* @param uid* @param title* @param content* @return*/public int update(Integer aid, Integer uid, String title, String content) {return articleMapper.update(aid, uid, title, content);}/*** 用户博客列表,删除文章** @param aid* @return*/public int delete(Integer aid) {return articleMapper.delete(aid);}/*** 博客编辑,发布文章** @param uid* @param title* @param content* @return*/public int add(Integer uid, String title, String content) {return articleMapper.add(uid, title, content);}
}
ArticleController:->add
package com.example.mycnblog.controller;import com.example.mycnblog.common.AjaxResult;
import com.example.mycnblog.common.Constant;
import com.example.mycnblog.common.SessionUtil;
import com.example.mycnblog.model.ArticleInfo;
import com.example.mycnblog.model.UserInfo;
import com.example.mycnblog.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.List;/**1. 文章控制器*/
@RestController
@RequestMapping("/art")
public class ArticleController {@Autowiredprivate ArticleService articleService;/*** 查询用户的所有文章** @param request* @return*/@RequestMapping("/mylist")public List myList(HttpServletRequest request) {UserInfo userInfo = SessionUtil.getLoginUser(request);if (userInfo != null) {return articleService.getMyList(userInfo.getId());}return null;}/*** 获取文章的详情信息** @param aid* @return*/@RequestMapping("/detail")public Object getDetil(Integer aid) {if (aid != null && aid > 0) {return AjaxResult.success(articleService.getDetil(aid));}return AjaxResult.fail(-1, "查询失败");}/*** 修改页面,查询文章** @param request* @param aid* @return*/@RequestMapping("/detailbyid")public Object getDetailById(HttpServletRequest request, Integer aid) {if (aid != null && aid > 0) {// 根据文章查询文章的详情ArticleInfo articleInfo = articleService.getDetil(aid);// 文章的归属人验证UserInfo userInfo = SessionUtil.getLoginUser(request);if (userInfo != null && articleInfo != null &&userInfo.getId() == articleInfo.getUid()) { // 文章归属人正确return AjaxResult.success(articleInfo);}}return AjaxResult.fail(-1, "查询失败");}/*** 修改页面,修改文章** @param request* @param aid* @param title* @param content* @return*/@RequestMapping("/update")public int update(HttpServletRequest request, Integer aid, String title, String content) {// 非空校验if (aid == null || !StringUtils.hasLength(title) || !StringUtils.hasLength(content)) {// 参数有误return 0;}UserInfo userInfo = SessionUtil.getLoginUser(request);if (userInfo != null && userInfo.getId() > 0) {return articleService.update(aid, userInfo.getId(), title, content);}return 0;}/*** 博客列表,删除文章** @param request* @param aid* @return*/@RequestMapping("/delete")public int delete(HttpServletRequest request, Integer aid) {// 非空校验if (aid == null && aid <= 0) {// 参数有误return 0;}UserInfo userInfo = SessionUtil.getLoginUser(request);if (userInfo != null) { // 当前已登录return articleService.delete(aid);}return 0;}/*** 博客编辑,发布文章** @param request* @param title* @param content* @return*/@RequestMapping("/add")public int add(HttpServletRequest request, String title, String content) {// 非空校验if (!StringUtils.hasLength(title) || !StringUtils.hasLength(content)) {// 参数有误return 0;}UserInfo userInfo = SessionUtil.getLoginUser(request);if (userInfo != null && userInfo.getId() > 0) {return articleService.add(userInfo.getId(), title, content);}return 0;}
}
进入个人博客列表:
点击写博客:
写一些内容点击,发布文章:
点击确定,发布文章成功:
发布前数据库信息:
发布后数据库信息:
blog_list.html:
博客列表
分页要素:
分页语法(SQL):
-- 注意 (PageIndex-1)*PageSize 这种sql是不对的,后端需要自行计算,然后传给mapper
limit PageSize offset (PageIndex-1)*PageSize
ArticleMapper:->getList
package com.example.mycnblog.mapper;import com.example.mycnblog.model.ArticleInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;import java.util.List;/*** 文章表的 mapper*/
@Mapper
public interface ArticleMapper {/*** 根据用户id(uid)查询所有文章** @param uid* @return*/public List getMyList(@Param("uid") Integer uid);/*** 分页——查询所有文章** @param Offset* @param PageSize* @return*/public List getList(@Param("Offset") Integer Offset,@Param("PageSize") Integer PageSize);/*** 根据文章id(id)获取文章的详情信息** @param aid* @return*/public ArticleInfo getDetail(@Param("aid") Integer aid);/*** 根据文章id(id)和用户id(uid)修改文章的标题和内容** @param aid* @param uid* @param title* @param content* @return*/public int update(@Param("aid") Integer aid,@Param("uid") Integer uid,@Param("title") String title,@Param("content") String content);/*** 根据文章id(id)删除文章** @param aid* @return*/public int delete(@Param("aid") Integer aid);/*** 添加文章(uid,文章标题,文章内容)** @param uid* @param title* @param content* @return*/public int add(@Param("uid") Integer uid,@Param("title") String title,@Param("content") String content);
}
ArticleMapper.xml:->getList
update articleinfoset title=#{title},content=#{content}where id = #{aid}and uid = #{uid} deletefrom articleinfowhere id = #{aid} insert into articleinfo(title, content, uid)values (#{title}, #{content}, #{uid});
ArticleService:->getList
package com.example.mycnblog.service;import com.example.mycnblog.mapper.ArticleMapper;
import com.example.mycnblog.model.ArticleInfo;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import javax.servlet.http.HttpServletRequest;
import java.util.List;/*** 文章表的服务层*/
@Service
public class ArticleService {@Autowiredprivate ArticleMapper articleMapper;/*** 用户博客列表,查询用户的所有文章** @param uid* @return*/public List getMyList(Integer uid) {return articleMapper.getMyList(uid);}/*** 分页——查询所有文章** @param Offset* @param PageSize* @return*/public List getList(Integer Offset, Integer PageSize) {return articleMapper.getList(Offset, PageSize);}/*** 用户博客列表,获取文章的详情信息** @param aid* @return*/public ArticleInfo getDetil(Integer aid) {return articleMapper.getDetail(aid);}/*** 修改页面,修改文章** @param aid* @param uid* @param title* @param content* @return*/public int update(Integer aid, Integer uid, String title, String content) {return articleMapper.update(aid, uid, title, content);}/*** 用户博客列表,删除文章** @param aid* @return*/public int delete(Integer aid) {return articleMapper.delete(aid);}/*** 博客编辑,发布文章** @param uid* @param title* @param content* @return*/public int add(Integer uid, String title, String content) {return articleMapper.add(uid, title, content);}
}
ArticleController:->getList
package com.example.mycnblog.controller;import com.example.mycnblog.common.AjaxResult;
import com.example.mycnblog.common.Constant;
import com.example.mycnblog.common.SessionUtil;
import com.example.mycnblog.model.ArticleInfo;
import com.example.mycnblog.model.UserInfo;
import com.example.mycnblog.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.List;/*** 文章控制器*/
@RestController
@RequestMapping("/art")
public class ArticleController {@Autowiredprivate ArticleService articleService;/*** 查询用户的所有文章** @param request* @return*/@RequestMapping("/mylist")public List myList(HttpServletRequest request) {UserInfo userInfo = SessionUtil.getLoginUser(request);if (userInfo != null) {return articleService.getMyList(userInfo.getId());}return null;}/*** 分页——查询所有文章** @param PageIndex* @param PageSize* @return*/@RequestMapping("/list")public List getList(Integer PageIndex, Integer PageSize) {if (PageIndex == null || PageSize == null || PageIndex <= 0 || PageSize <= 0) {return null;}// 分页公式,计算偏移量int Offset = (PageIndex - 1) * PageSize;return articleService.getList(Offset, PageSize);}/*** 获取文章的详情信息** @param aid* @return*/@RequestMapping("/detail")public Object getDetil(Integer aid) {if (aid != null && aid > 0) {return AjaxResult.success(articleService.getDetil(aid));}return AjaxResult.fail(-1, "查询失败");}/*** 修改页面,查询文章** @param request* @param aid* @return*/@RequestMapping("/detailbyid")public Object getDetailById(HttpServletRequest request, Integer aid) {if (aid != null && aid > 0) {// 根据文章查询文章的详情ArticleInfo articleInfo = articleService.getDetil(aid);// 文章的归属人验证UserInfo userInfo = SessionUtil.getLoginUser(request);if (userInfo != null && articleInfo != null &&userInfo.getId() == articleInfo.getUid()) { // 文章归属人正确return AjaxResult.success(articleInfo);}}return AjaxResult.fail(-1, "查询失败");}/*** 修改页面,修改文章** @param request* @param aid* @param title* @param content* @return*/@RequestMapping("/update")public int update(HttpServletRequest request, Integer aid, String title, String content) {// 非空校验if (aid == null || !StringUtils.hasLength(title) || !StringUtils.hasLength(content)) {// 参数有误return 0;}UserInfo userInfo = SessionUtil.getLoginUser(request);if (userInfo != null && userInfo.getId() > 0) {return articleService.update(aid, userInfo.getId(), title, content);}return 0;}/*** 博客列表,删除文章** @param request* @param aid* @return*/@RequestMapping("/delete")public int delete(HttpServletRequest request, Integer aid) {// 非空校验if (aid == null && aid <= 0) {// 参数有误return 0;}UserInfo userInfo = SessionUtil.getLoginUser(request);if (userInfo != null) { // 当前已登录return articleService.delete(aid);}return 0;}/*** 博客编辑,发布文章** @param request* @param title* @param content* @return*/@RequestMapping("/add")public int add(HttpServletRequest request, String title, String content) {// 非空校验if (!StringUtils.hasLength(title) || !StringUtils.hasLength(content)) {// 参数有误return 0;}UserInfo userInfo = SessionUtil.getLoginUser(request);if (userInfo != null && userInfo.getId() > 0) {return articleService.add(userInfo.getId(), title, content);}return 0;}
}
这里放行,是因为这个博客列表是所有文章的列表,用户不需要登录就可以访问。
AppConfig:->放行文章分页列表
package com.example.mycnblog.common;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import java.util.ArrayList;
import java.util.List;/*** 配置拦截器*/
@Configuration
public class AppConfig implements WebMvcConfigurer {// 不拦截的 url 集合List excludes = new ArrayList(){{add("/**/*.html");add("/js/**"); // 放行 static/js 下的所有文件add("/editor.md/**"); // 放行 static/editor.md 下的所有文件add("/css/**"); // 放行 static/css 下的所有文件add("/img/**"); // 放行 static/img 下的所有文件add("/user/reg"); // 放行注册接口add("/user/login"); // 放行登录接口add("/art/detail"); // 放行文章详情接口add("/art/list"); // 放行文章分页列表}};@Autowiredprivate LoginInterceptor loginInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 配置拦截器InterceptorRegistration registration =registry.addInterceptor(loginInterceptor);registration.addPathPatterns("/**"); // 拦截所有请求registration.excludePathPatterns(excludes); // 排除不拦截的 url}
}
尾页:这里计算尾页的方法,主要是文章总数 / 每页容量,但是要向上进位。
例如——5 / 2 = 2.5 -> 3,这里的进位可以采用 Math 类里的 ceil 方法;但是又有一个问题,对于 int 类型 5 / 2 = 2,所以要再 * 1.0,这样就是 2.5 了。
ArticleMapper:->getTotalCount
package com.example.mycnblog.mapper;import com.example.mycnblog.model.ArticleInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;import java.util.List;/*** 文章表的 mapper*/
@Mapper
public interface ArticleMapper {/*** 根据用户id(uid)查询所有文章** @param uid* @return*/public List getMyList(@Param("uid") Integer uid);/*** 分页——查询所有文章** @param Offset* @param PageSize* @return*/public List getList(@Param("Offset") Integer Offset,@Param("PageSize") Integer PageSize);/*** 跳转文章列表尾页——查询文章总数** @return*/public int getTotalCount();/*** 根据文章id(id)获取文章的详情信息** @param aid* @return*/public ArticleInfo getDetail(@Param("aid") Integer aid);/*** 根据文章id(id)和用户id(uid)修改文章的标题和内容** @param aid* @param uid* @param title* @param content* @return*/public int update(@Param("aid") Integer aid,@Param("uid") Integer uid,@Param("title") String title,@Param("content") String content);/*** 根据文章id(id)删除文章** @param aid* @return*/public int delete(@Param("aid") Integer aid);/*** 添加文章(uid,文章标题,文章内容)** @param uid* @param title* @param content* @return*/public int add(@Param("uid") Integer uid,@Param("title") String title,@Param("content") String content);
}
ArticleMapper.xml:->getTotalCount
update articleinfoset title=#{title},content=#{content}where id = #{aid}and uid = #{uid} deletefrom articleinfowhere id = #{aid} insert into articleinfo(title, content, uid)values (#{title}, #{content}, #{uid});
ArticleService:
package com.example.mycnblog.service;import com.example.mycnblog.mapper.ArticleMapper;
import com.example.mycnblog.model.ArticleInfo;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import javax.servlet.http.HttpServletRequest;
import java.util.List;/*** 文章表的服务层*/
@Service
public class ArticleService {@Autowiredprivate ArticleMapper articleMapper;/*** 用户博客列表,查询用户的所有文章** @param uid* @return*/public List getMyList(Integer uid) {return articleMapper.getMyList(uid);}/*** 分页——查询所有文章** @param Offset* @param PageSize* @return*/public List getList(Integer Offset, Integer PageSize) {return articleMapper.getList(Offset, PageSize);}/*** 跳转文章列表尾页——查询文章总数** @return*/public int getTotalCount() {return articleMapper.getTotalCount();}/*** 用户博客列表,获取文章的详情信息** @param aid* @return*/public ArticleInfo getDetil(Integer aid) {return articleMapper.getDetail(aid);}/*** 修改页面,修改文章** @param aid* @param uid* @param title* @param content* @return*/public int update(Integer aid, Integer uid, String title, String content) {return articleMapper.update(aid, uid, title, content);}/*** 用户博客列表,删除文章** @param aid* @return*/public int delete(Integer aid) {return articleMapper.delete(aid);}/*** 博客编辑,发布文章** @param uid* @param title* @param content* @return*/public int add(Integer uid, String title, String content) {return articleMapper.add(uid, title, content);}
}
ArticleController:
package com.example.mycnblog.controller;import com.example.mycnblog.common.AjaxResult;
import com.example.mycnblog.common.Constant;
import com.example.mycnblog.common.SessionUtil;
import com.example.mycnblog.model.ArticleInfo;
import com.example.mycnblog.model.UserInfo;
import com.example.mycnblog.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.List;/*** 文章控制器*/
@RestController
@RequestMapping("/art")
public class ArticleController {@Autowiredprivate ArticleService articleService;/*** 查询用户的所有文章** @param request* @return*/@RequestMapping("/mylist")public List myList(HttpServletRequest request) {UserInfo userInfo = SessionUtil.getLoginUser(request);if (userInfo != null) {return articleService.getMyList(userInfo.getId());}return null;}/*** 分页——查询所有文章** @param PageIndex* @param PageSize* @return*/@RequestMapping("/list")public List getList(Integer PageIndex, Integer PageSize) {if (PageIndex == null || PageSize == null || PageIndex <= 0 || PageSize <= 0) {return null;}// 分页公式,计算偏移量int Offset = (PageIndex - 1) * PageSize;return articleService.getList(Offset, PageSize);}/*** 跳转文章列表尾页——获取尾页** @param PageSize* @return*/@RequestMapping("/totalpage")public Integer getTotalPage(Integer PageSize) {if (PageSize != null && PageSize > 0) {// 参数有效// 文章总数int TotalCount = articleService.getTotalCount();// 总页数int TotalPage = (int) Math.ceil(TotalCount * 1.0 / PageSize);return TotalPage;}return null;}/*** 获取文章的详情信息** @param aid* @return*/@RequestMapping("/detail")public Object getDetil(Integer aid) {if (aid != null && aid > 0) {return AjaxResult.success(articleService.getDetil(aid));}return AjaxResult.fail(-1, "查询失败");}/*** 修改页面,查询文章** @param request* @param aid* @return*/@RequestMapping("/detailbyid")public Object getDetailById(HttpServletRequest request, Integer aid) {if (aid != null && aid > 0) {// 根据文章查询文章的详情ArticleInfo articleInfo = articleService.getDetil(aid);// 文章的归属人验证UserInfo userInfo = SessionUtil.getLoginUser(request);if (userInfo != null && articleInfo != null &&userInfo.getId() == articleInfo.getUid()) { // 文章归属人正确return AjaxResult.success(articleInfo);}}return AjaxResult.fail(-1, "查询失败");}/*** 修改页面,修改文章** @param request* @param aid* @param title* @param content* @return*/@RequestMapping("/update")public int update(HttpServletRequest request, Integer aid, String title, String content) {// 非空校验if (aid == null || !StringUtils.hasLength(title) || !StringUtils.hasLength(content)) {// 参数有误return 0;}UserInfo userInfo = SessionUtil.getLoginUser(request);if (userInfo != null && userInfo.getId() > 0) {return articleService.update(aid, userInfo.getId(), title, content);}return 0;}/*** 博客列表,删除文章** @param request* @param aid* @return*/@RequestMapping("/delete")public int delete(HttpServletRequest request, Integer aid) {// 非空校验if (aid == null && aid <= 0) {// 参数有误return 0;}UserInfo userInfo = SessionUtil.getLoginUser(request);if (userInfo != null) { // 当前已登录return articleService.delete(aid);}return 0;}/*** 博客编辑,发布文章** @param request* @param title* @param content* @return*/@RequestMapping("/add")public int add(HttpServletRequest request, String title, String content) {// 非空校验if (!StringUtils.hasLength(title) || !StringUtils.hasLength(content)) {// 参数有误return 0;}UserInfo userInfo = SessionUtil.getLoginUser(request);if (userInfo != null && userInfo.getId() > 0) {return articleService.add(userInfo.getId(), title, content);}return 0;}
}
同理,这里也需要放行。
AppConfig:->放行文章分页总页数接口
package com.example.mycnblog.common;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import java.util.ArrayList;
import java.util.List;/*** 配置拦截器*/
@Configuration
public class AppConfig implements WebMvcConfigurer {// 不拦截的 url 集合List excludes = new ArrayList(){{add("/**/*.html");add("/js/**"); // 放行 static/js 下的所有文件add("/editor.md/**"); // 放行 static/editor.md 下的所有文件add("/css/**"); // 放行 static/css 下的所有文件add("/img/**"); // 放行 static/img 下的所有文件add("/user/reg"); // 放行注册接口add("/user/login"); // 放行登录接口add("/art/detail"); // 放行文章详情接口add("/art/list"); // 放行文章分页列表接口add("/art/totalpage"); // 放行文章分页总页数接口 }};@Autowiredprivate LoginInterceptor loginInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {// 配置拦截器InterceptorRegistration registration =registry.addInterceptor(loginInterceptor);registration.addPathPatterns("/**"); // 拦截所有请求registration.excludePathPatterns(excludes); // 排除不拦截的 url}
}
进入文章分页列表:
点击尾页:
很多人其实在这里会用到 md5,直接加盐,但是实际上这种方式并不好,虽然 md5 加密是不可逆的,但是由于 md5 加密的相同密码对应的加密后密码相同,并且都是32位的,这样我们就可以做一个彩虹表,来破解了。
理想的加盐方式,其实就是我们每一次都随机盐值,这样加密出来的密码,想要破解就会浪费大量的时间,安全性也更高了。
既然加密了,那肯定就要有验证密码,我们验证密码需要三个数据,一个是待验证的密码,一个是盐值,一个是已经加密后的密码。所以我们其实可以将验证和加密后的密码拼接起来,这样我们的密码长度也很长,然后我们可以再用 md5 进行加密,因为 md5 加密后,密文都是32位的,这样我们就可以根据位数进行分割盐值和密码。
通过上述分析,公式为:
最终密码 = (md5)(盐值 + 原始密码)
common->SecurityUtil:
package com.example.mycnblog.common;import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;import java.util.UUID;/*** 加盐加密类*/
public class SecurityUtil {/*** 加盐加密** @param password* @return*/public static String encrypt(String password) {// 每次生成内容不同的,但长度固定的 32 位盐值String salt = UUID.randomUUID().toString().replace("-", "");// 最终密码 = (md5)(盐值 + 原始密码)String finalPassword = DigestUtils.md5DigestAsHex((salt + password).getBytes());return salt + finalPassword;}/*** 密码验证** @param password 待验证密码* @param finalPassword 数据库中加盐的密码* @return*/public static boolean decrypt(String password, String finalPassword) {// 非空效验if (!StringUtils.hasLength(password) || !StringUtils.hasLength(finalPassword)) {return false;}// 最终密码不正确if (finalPassword.length() != 64) {return false;}// 获取盐值String salt = finalPassword.substring(0, 32);// 加盐密码 = (md5)(盐值 + 待确定密码)String securityPassword =DigestUtils.md5DigestAsHex((salt + password).getBytes());// (盐值 + 加盐密码) 与 (最终密码) 进行比较return (salt + securityPassword).equals(finalPassword);}
}
这个地方主要是要修改注册和登录这两个接口。
UserMapper:->getUserByName
package com.example.mycnblog.mapper;import com.example.mycnblog.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;/*** 用户表的 mapper*/
@Mapper
public interface UserMapper {/*** 用户注册** @param username* @param password* @return*/public int add(@Param("username") String username,@Param("password") String password);/*** 用户登录** @param username* @param password* @return*/public UserInfo login(@Param("username") String username,@Param("password") String password);/*** 根据用户名获取用户信息** @param username* @return*/public UserInfo getUserByName(@Param("username") String username);/*** 通过用户 id 查询用户信息** @param uid* @return*/public UserInfo myInfoByUid(@Param("uid") Integer uid);
}
UserMapper.xml:->getUserByName
insert into userinfo(username, password)values (#{username}, #{password})
UserService:->getUserByName
package com.example.mycnblog.service;import com.example.mycnblog.mapper.UserMapper;
import com.example.mycnblog.model.UserInfo;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;/*** 用户表的服务层*/
@Service
public class UserService {@Autowiredprivate UserMapper userMapper;/*** 用户注册** @param username* @param password* @return*/public int add(String username, String password) {return userMapper.add(username, password);}/*** 用户登录** @param username* @param password* @return*/public UserInfo login(String username, String password) {return userMapper.login(username, password);}/*** 用户登录——根据用户名获取用户信息** @param username* @return*/public UserInfo getUserByName(String username) {return userMapper.getUserByName(username);}/*** 获取作者信息** @param uid* @return*/public UserInfo myInfoByUid(Integer uid) {return userMapper.myInfoByUid(uid);}
}
UserController:->reg / login
package com.example.mycnblog.controller;import com.example.mycnblog.common.AjaxResult;
import com.example.mycnblog.common.Constant;
import com.example.mycnblog.common.SecurityUtil;
import com.example.mycnblog.model.UserInfo;
import com.example.mycnblog.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;/*** 用户控制器*/
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;/*** 用户注册** @param username* @param password* @return*/@RequestMapping("/reg")public Object reg(String username, String password) {// 1.非空效验if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {return AjaxResult.fail(-1, "非法的参数请求!");}// 2.进行添加操作int result = userService.add(username, SecurityUtil.encrypt(password));if (result == 1) {return AjaxResult.success("注册成功!", 1);} else {return AjaxResult.fail(-1, "数据库添加出错!");}}/*** 用户登录** @param username* @param password* @return 如果用户名和密码都正确,返回1;如果用户名或密码为空/不正确,返回非1*/@RequestMapping("/login")public int login(HttpServletRequest request, String username, String password) {// 1.非空效验if (!StringUtils.hasLength(username) || !StringUtils.hasLength(password)) {// 参数有误return 0;}// 2.进行查找操作UserInfo userInfo = userService.getUserByName(username);if (userInfo == null || userInfo.getId() <= 0) { // userinfo 无效// 用户名错误return -1;} else {// 用户名正确boolean result = SecurityUtil.decrypt(password, userInfo.getPassword());if (result) {// 密码正确// 将 userinfo 保存到 session 中HttpSession session = request.getSession();session.setAttribute(Constant.SESSION_USERINFO_KEY, userInfo);return 1;}// 密码错误return -1;}}/*** 退出登录** @param request* @return*/@RequestMapping("/logout")public boolean logout(HttpServletRequest request) {HttpSession session = request.getSession(false);if (session != null &&session.getAttribute(Constant.SESSION_USERINFO_KEY) != null) {// 移除 session 中当前登录的用户session.removeAttribute(Constant.SESSION_USERINFO_KEY);}return true;}/*** 获取个人信息** @param request* @return*/@RequestMapping("/myinfo")public UserInfo myInfo(HttpServletRequest request) {HttpSession session = request.getSession(false);if (session != null &&session.getAttribute(Constant.SESSION_USERINFO_KEY) != null) {return (UserInfo) session.getAttribute(Constant.SESSION_USERINFO_KEY);}return null;}/*** 获取作者信息** @param uid* @return*/@RequestMapping("/myinfobyuid")public UserInfo myInfoByUid(Integer uid) {if (uid != null && uid > 0) {return userService.myInfoByUid(uid);}return null;}
}
来到注册页面:李四 / 123456
来到登录页面:李四 / 123456
这个项目还是花了很多功夫的,完成之后也是松了一口气,复习了很多知识,也从中学到了一些新知识,文章中实现的功能都是一些基础部分,还有一些进阶部分,各位可以自行实现!
可扩展功能: