目录
代码获取:基于Servlet实现博客系统--- 前后端分离: 基于Servlet实现博客系统--- 前后端分离
一.博客系统概述
1.软件的生命周期
- 可行性研究
- 需求分析—需求文档
- 概要设计
- 详细设计
- 开发
- 集成测试
- 验收测试
- 上线运行
- 维护
- 退役
2.学习目标
- 熟悉前端怎么发送数据
- 后端怎么接收数据
- 熟悉前后端交互过程中参数的解析方式(前后端要约定好)
- 后端接收到参数之后要做哪些校验
- 数据库如何操作
- 后端返回什么样的结果给前端
- 前端拿到服务器的响应之后做什么样的处理
二.数据库的建立
1.创建数据库和表
#设置数据库的编码集和排序忽略大小写
create database blog_db character set utf8mb4 collate utf8mb4_general_ci;
#建立user表
create table user(
id bigint primary key auto_increment comment '用户id,自增',
username varchar(50) unique not null comment '用户名',
password varchar(50) not null comment '密码'
);
#建立blog表
create table blog(
id bigint primary key auto_increment comment '博客id,自增',
title varchar(1024) not null comment '标题',
cotent text not null comment '内容',
createtime datetime not null comment '发布时间',
userid bigint comment '用户id',
foreign key (userid) references user(id)
);
insert into blog values(null,'我的铅笔','“铅笔,铅笔,5角一支呀!”,“橡皮5折啦,1元一块!”,还没进班,我就听到了这样的吆喝声,小学作文。
进了教室,只见桌椅摆成了柜台的形状,桌子上摆着各种各样的商品,琳琅满目。只见同学们有的在选购自己喜爱的商品,有的在边走边推销,说着:“只要是 想买,我可以给你打七折”,还有的坐在位子上吆喝着:“走过路过,不要错过,”“不看不知道,一看忘不掉!”看见这些情景,我也从书包中拿出我要卖的东 西。我卖的是一个神奇的魔术橡皮盒,它是天蓝色的,正面写着baby bear
魔术橡皮盒。为什么叫魔术橡皮盒呢?原来它可以变魔术,你把抽屉拉开时里面什么也没有,而当你把左侧一个开关推开,再打开抽屉时,里面便会出现一块精 致的小橡皮。这时周 走过来说:“赵越伟,我用这个小火车,小老鼠玩具和这个夹心饼换你的魔术橡皮盒可以吗?”我看了看他的小火车,很好玩,而且我们又是好朋友,于是便和他换 了。程博威这时也在吆喝:“可爱的小狗玩具呀!快来买呀!快来买呀!”我走过去跟他说:“我用这个小火车和你换行吗?”他说:“不行,这个别人已经有人定 购了。”这样的交易活动持续了很久,大家都很开心。
虽然我没有真正当过商人,可我已经感受到:“当商人真的不容易呀!只有想方设法吸引顾客,才能把自己的商品推销出去。”
',now(),1);
INSERT INTO blog VALUES(NULL,'测试1','测试内容',NOW(),2)
2.插入数据
#插入数据
insert into user values(null,'张三','123456'),(null,'李四','123456');
三.创建项目
1.建立maven项目
2.导入相关的依赖
<dependencies>
<!-- servlet依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<!-- 数据库连接依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- json依赖-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.2</version>
</dependency>
</dependencies>
3.编写工具类
1.编写数据库相关的工具类
采用单例模式创建数据库的工具类
package com.javastudy.utils;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* @author Chooker
* @create 2023-07-04 20:00
*/
public class DButils {
private static DataSource dataSource;
private static final String URL = "jdbc:mysql://localhost:13306/blog_db?characterEncoding=utf8&useSSL=false";
private static final String USER = "root";
private static final String PASSWORD = "woaini520";
//单例模式
private DButils() {
}
static {
MysqlDataSource mysqlDataSource = new MysqlDataSource();
mysqlDataSource.setURL(URL);
mysqlDataSource.setUser(USER);
mysqlDataSource.setPassword(PASSWORD);
dataSource = mysqlDataSource;
}
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
public static void close(ResultSet set, PreparedStatement statement, Connection connection) {
if (set != null) {
try {
set.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
2.编写字符串的工具类
package com.javastudy.utils;
/**
* @author Chooker
* @create 2023-07-04 20:35
*/
public class Stringutils {
/**
* 校验字符串是否为空
* @param value
* @return
*/
public static boolean isEmpty(String value) {
if (value == null || "".equals(value)) {
return true;
}
return false;
}
}
3.编写用户的工具类
package com.javastudy.utils;
import com.javastudy.common.AppConfig;
import com.javastudy.entities.User;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
/**
* @author Chooker
* @create 2023-07-06 21:29
*/
public class UserUtils {
public static User checkUserLoginStatus(HttpServletRequest req) {
//判断req对象是否为空
if (req == null) {
return null;
}
HttpSession session = req.getSession(false);
if (session == null) {
return null;
}
User user = (User) session.getAttribute(AppConfig.USER_SESSION_KEY);
return user;
}
}
4.创建实体类
1.创建user实体类
生成相对应的get和set方法和toString()方法(当然也可以使用lombok注解)
package com.javastudy.entities;
import com.fasterxml.jackson.annotation.JsonIgnore;
/**
* @author Chooker
* @create 2023-07-04 20:15
*/
public class User {
private Long id;
private String username;
@JsonIgnore //不参与json序列化
private String password;
private boolean isAuthor;
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", isAuthor=" + isAuthor +
'}';
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean isAuthor() {
return isAuthor;
}
public void setAuthor(boolean author) {
isAuthor = author;
}
public User() {
}
public User(Long id, String username, String password) {
this.id = id;
this.username = username;
this.password = password;
}
}
注意:最好在password上面加上JsonIgnore注解,这样在进行json序列化的时候,不会序列化password序列.加之前和之后的区别:可以看到密码没有进行json序列化
2.创建blog实体类
package com.javastudy.entities;
import java.sql.Timestamp;
/**
* @author Chooker
* @create 2023-07-04 20:17
*/
public class Blog {
private Long id;
private String title;
private String content;
private Timestamp createTime;
private Long userId;
@Override
public String toString() {
return "Blog{" +
"id=" + id +
", title='" + title + '\'' +
", content='" + content + '\'' +
", createTime=" + createTime +
", userId=" + userId +
'}';
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Timestamp getCreateTime() {
return createTime;
}
public void setCreateTime(Timestamp createTime) {
this.createTime = createTime;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public Blog(Long id, String title, String content, Timestamp createTime, Long userId) {
this.id = id;
this.title = title;
this.content = content;
this.createTime = createTime;
this.userId = userId;
}
public Blog() {
}
}
5.创建dao层(与数据库交互)
1.UserDao
1.实现登录功能
package com.javastudy.dao;
import com.javastudy.entities.User;
import com.javastudy.utils.DBUtils;
import com.javastudy.utils.StringUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* @author Chooker
* @create 2023-07-04 20:33
*/
public class UserDao {
/**
* 根据用户名查询用户信息
*
* @param username
* @return
*/
public User selectByUsername(String username) {
//非空校验
if (StringUtils.isEmpty(username)) {
return null;
}
//进行数据库的查询操作
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
//1.获取数据库的连接
connection = DBUtils.getConnection();
//2.定义sql语句
String sql = "select * from user where username=?";
//3.对sql语句进行预处理
preparedStatement = connection.prepareStatement(sql);
//4.设置占位符的值
preparedStatement.setString(1, username);
//5.执行sql并获取结果
resultSet = preparedStatement.executeQuery();
//6.构建查询出来的user对象
if (resultSet.next()) {
User user = new User();
user.setId(resultSet.getLong(1));
user.setUsername(resultSet.getString(2));
user.setPassword(resultSet.getString(3));
return user;
}
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
DBUtils.close(resultSet, preparedStatement, connection);
}
return null;
}
/**
* 根据用户id查询用户信息
*
* @param id
* @return
*/
public User selectById(Long id) {
if (id == null || id < 0) {
return null;
}
//进行数据库的查询操作
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
connection = DBUtils.getConnection();
String sql = "select id,username,password from user where id=?";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setLong(1, id);
resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
User user = new User();
user.setId(resultSet.getLong(1));
user.setUsername(resultSet.getString(2));
user.setPassword(resultSet.getString(3));
return user;
}
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
DBUtils.close(resultSet, preparedStatement, connection);
}
return null;
}
}
2.BlogDao
package com.javastudy.dao;
import com.javastudy.entities.Blog;
import com.javastudy.utils.DBUtils;
import com.javastudy.utils.StringUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* @author Chooker
* @create 2023-07-04 20:33
*/
public class BlogDao {
/**
* 查询所有的博客信息
*
* @return
*/
public List<Blog> selectAll() {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
connection = DBUtils.getConnection();
String sql = "select id,title,content,createTime,userId from blog order by createTime desc";
preparedStatement = connection.prepareStatement(sql);
List<Blog> list = null;
resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
if (list == null) {
list = new ArrayList<>();
}
Blog blog = new Blog();
blog.setId(resultSet.getLong(1));
blog.setTitle(resultSet.getString(2));
blog.setContent(resultSet.getString(3));
blog.setCreateTime(resultSet.getTimestamp(4));
blog.setUserId(resultSet.getLong(5));
list.add(blog);
}
return list;
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
DBUtils.close(resultSet, preparedStatement, connection);
}
}
/**
* 根据博客id查询博客信息
*
* @param id
* @return
*/
public Blog selectById(Long id) {
if (id == null || id < 0) {
return null;
}
//进行数据库的查询操作
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
connection = DBUtils.getConnection();
String sql = "select id,title,content,createTime,userId from blog where id=?";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setLong(1, id);
resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
Blog blog = new Blog();
blog.setId(resultSet.getLong(1));
blog.setTitle(resultSet.getString(2));
blog.setContent(resultSet.getString(3));
blog.setCreateTime(resultSet.getTimestamp(4));
blog.setUserId(resultSet.getLong(5));
return blog;
}
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
DBUtils.close(resultSet, preparedStatement, connection);
}
return null;
}
/**
* 发布一篇博客
*
* @param blog
* @return 发布了多少条博客
*/
public int insert(Blog blog) {
if (blog == null || StringUtils.isEmpty(blog.getTitle()) || StringUtils.isEmpty(blog.getContent())
|| blog.getUserId() == null) {
return 0;
}
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = DBUtils.getConnection();
String sql = "insert into blog values(null,?,?,?,?)";
//预处理sql
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, blog.getTitle());
preparedStatement.setString(2, blog.getContent());
preparedStatement.setTimestamp(3, blog.getCreateTime());
preparedStatement.setLong(4, blog.getUserId());
return preparedStatement.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
DBUtils.close(null, preparedStatement, connection);
}
}
}
5.4测试DAO层
1.TestUserDao
import com.javastudy.dao.UserDao;
import com.javastudy.entities.User;
import org.junit.Test;
/**
* @author Chooker
* @create 2023-07-06 21:12
*/
public class TestUser {
@Test
public void test01(){
UserDao userDao=new UserDao();
User user = userDao.selectByUsername("张三");
System.out.println(user);
}
}
2.TestBlogDao
import com.javastudy.dao.BlogDao;
import com.javastudy.entities.Blog;
import org.junit.Test;
import java.util.List;
/**
* @author Chooker
* @create 2023-07-06 21:05
*/
public class TestBlog {
@Test
public void test01(){
BlogDao blogDao = new BlogDao();
List<Blog> blogs = blogDao.selectAll();
System.out.println(blogs);
}
}
5.5编写Common层
1.AppResult
package com.javastudy.common;
/**
* @author Chooker
* @create 2023-07-05 11:24
*/
public class AppResult<T> {
//状态码
private Integer code;
//描述信息
private String message;
//相关数据
private T data;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public AppResult(Integer code, String message, T data) {
this.code = code;
this.message = message;
this.data = data;
}
public static <T> AppResult success(T data) {
return new AppResult(0, "操作成功", data);
}
public static <T> AppResult success(String message) {
return new AppResult(0, message, null);
}
public static <T> AppResult success() {
return new AppResult(0, "操作成功", null);
}
public static <T> AppResult fail(String message) {
return new AppResult(-1, message, null);
}
public static <T> AppResult fail() {
return new AppResult(-1, "操作失败", null);
}
}
2.AppConfig
package com.javastudy.common;
/**
* @author Chooker
* @create 2023-07-05 17:37
*/
public class AppConfig {
public static final String USER_SESSION_KEY="USERSESSIONKEY";
}
6.创建servlet层
1.LoginServlet
package com.javastudy.servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.javastudy.common.AppConfig;
import com.javastudy.common.AppResult;
import com.javastudy.dao.UserDao;
import com.javastudy.entities.User;
import com.javastudy.utils.Stringutils;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* @author Chooker
* @create 2023-07-04 21:00
*/
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
ObjectMapper objectMapper = new ObjectMapper();
UserDao userDao = new UserDao();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置编码集
req.setCharacterEncoding("utf-8");
resp.setContentType("application/json;charset=utf-8");
String username = req.getParameter("username");
String password = req.getParameter("password");
if (Stringutils.isEmpty(username) || Stringutils.isEmpty(password)) {
AppResult appResult = AppResult.fail("用户名或者密码为空");
resp.getWriter().write(objectMapper.writeValueAsString(appResult));
return;
}
User user = userDao.selectByUsername(username);
if (user == null) {
AppResult appResult = AppResult.fail("用户名不存在");
resp.getWriter().write(objectMapper.writeValueAsString(appResult));
return;
}
//验证密码是否错误
if (!user.getPassword().equals(password)) {
AppResult appResult = AppResult.fail("密码错误");
resp.getWriter().write(objectMapper.writeValueAsString(appResult));
return;
}
//登录成功 保存用户信息到session中
HttpSession session = req.getSession(true);
AppResult appResult = AppResult.success("登录成功");
//使用全局定义的sessionKey
session.setAttribute(AppConfig.USER_SESSION_KEY, user);
resp.getWriter().write(objectMapper.writeValueAsString(appResult));
}
}
2.UserServlet
package com.javastudy.servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.javastudy.common.AppConfig;
import com.javastudy.common.AppResult;
import com.javastudy.dao.BlogDao;
import com.javastudy.dao.UserDao;
import com.javastudy.entities.Blog;
import com.javastudy.entities.User;
import com.javastudy.utils.StringUtils;
import com.javastudy.utils.UserUtils;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* @author Chooker
* @create 2023-07-06 15:05
*/
@WebServlet("/user")
public class UserServlet extends HttpServlet {
private ObjectMapper objectMapper = new ObjectMapper();
private UserDao userDao = new UserDao();
private BlogDao blogDao = new BlogDao();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("application/json;charset=utf-8");
HttpSession session = req.getSession(false);
//判断session
if (UserUtils.checkUserLoginStatus(req) == null) {
//设置状态码 403 表示用户没有权限
resp.setStatus(403);
//错误描述
AppResult appResult = AppResult.fail("用户没有登录,请登录后再试");
//代表用户没有登录
resp.getWriter().write(objectMapper.writeValueAsString(appResult));
return;
}
String blogId = req.getParameter("blogId");
String jsonStr = null;
if (StringUtils.isEmpty(blogId)) {
User user = (User) session.getAttribute(AppConfig.USER_SESSION_KEY);
jsonStr = objectMapper.writeValueAsString(AppResult.success(user));
} else {
Blog blog = blogDao.selectById(Long.valueOf(blogId));
if (blog == null) {
resp.getWriter().write(objectMapper.writeValueAsString(AppResult.fail("没有找到对应的博客")));
return;
}
User user = userDao.selectById(blog.getUserId());
jsonStr = objectMapper.writeValueAsString(AppResult.success(user));
}
//返回json
resp.getWriter().write(jsonStr);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
3.BlogServlet
package com.javastudy.servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.javastudy.common.AppResult;
import com.javastudy.dao.BlogDao;
import com.javastudy.entities.Blog;
import com.javastudy.entities.User;
import com.javastudy.utils.StringUtils;
import com.javastudy.utils.UserUtils;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
/**
* @author Chooker
* @create 2023-07-06 21:16
*/
@WebServlet("/blog")
public class BlogServlet extends HttpServlet {
BlogDao blogDao = new BlogDao();
ObjectMapper objectMapper = new ObjectMapper();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("application/json;charset=utf-8");
//校验用户登录状态
HttpSession session = req.getSession(false);
//判断session
if (UserUtils.checkUserLoginStatus(req) == null) {
//设置状态码 403 表示用户没有权限
resp.setStatus(403);
//错误描述
AppResult appResult = AppResult.fail("用户没有登录,请登录后再试");
//代表用户没有登录
resp.getWriter().write(objectMapper.writeValueAsString(appResult));
return;
}
String blogId = req.getParameter("blogId");
String jsonStr = null;
if (StringUtils.isEmpty(blogId)) {
List<Blog> blogs = blogDao.selectAll();
//非空的校验
if (blogs == null) {
blogs = new ArrayList<>();
}
jsonStr = objectMapper.writeValueAsString(AppResult.success(blogs));
} else {
Blog blog = blogDao.selectById(Long.valueOf(blogId));
if (blog == null) {
resp.getWriter().write(objectMapper.writeValueAsString(AppResult.fail("没有找到对应的博客")));
return;
}
jsonStr = objectMapper.writeValueAsString(AppResult.success(blog));
}
resp.getWriter().write(jsonStr);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("application/json;charset=utf-8");
//校验用户登录状态
HttpSession session = req.getSession(false);
User user = UserUtils.checkUserLoginStatus(req);
//判断session
if (user == null) {
//设置状态码 403 表示用户没有权限
resp.setStatus(403);
//错误描述
AppResult appResult = AppResult.fail("用户没有登录,请登录后再试");
//代表用户没有登录
resp.getWriter().write(objectMapper.writeValueAsString(appResult));
return;
}
String title = req.getParameter("title");
String content = req.getParameter("content");
if (StringUtils.isEmpty(title) || StringUtils.isEmpty(content)) {
AppResult appResult = AppResult.fail("文章的标题或者内容为空");
//代表用户没有登录
resp.getWriter().write(objectMapper.writeValueAsString(appResult));
return;
}
Blog blog = new Blog();
blog.setTitle(title);
blog.setContent(content);
blog.setCreateTime(Timestamp.valueOf(LocalDateTime.now()));
blog.setUserId(user.getId());
int insert = blogDao.insert(blog);
if (insert <= 0) {
AppResult appResult = AppResult.fail("文章发布失败,请重新发布");
//代表用户没有登录
resp.getWriter().write(objectMapper.writeValueAsString(appResult));
return;
}
resp.getWriter().write(objectMapper.writeValueAsString(AppResult.success("发布成功")));
}
@Override
protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("application/json;charset=utf-8");
//校验用户登录状态
HttpSession session = req.getSession(false);
User user = UserUtils.checkUserLoginStatus(req);
//判断session
if (user == null) {
//设置状态码 403 表示用户没有权限
resp.setStatus(403);
//错误描述
AppResult appResult = AppResult.fail("用户没有登录,请登录后再试");
//代表用户没有登录
resp.getWriter().write(objectMapper.writeValueAsString(appResult));
return;
}
String blogId = req.getParameter("blogId");
Blog blog = blogDao.selectById(Long.valueOf(blogId));
if (blog == null) {
resp.getWriter().write(objectMapper.writeValueAsString(AppResult.fail("不存在这个博客")));
return;
}
if (blog.getUserId() != user.getId()) {
resp.getWriter().write(objectMapper.writeValueAsString(AppResult.fail("无权删除别人的博客")));
return;
}
if (StringUtils.isEmpty(blogId)) {
resp.getWriter().write(objectMapper.writeValueAsString(AppResult.fail("参数校验失败")));
return;
}
//调用DAO进行删除操作
int row = blogDao.deleteById(Long.valueOf(blogId));
if (row != 1) {
resp.getWriter().write(objectMapper.writeValueAsString(AppResult.fail("删除失败")));
return;
}
resp.getWriter().write(objectMapper.writeValueAsString(AppResult.success("删除成功")));
}
}
4.LogoutServlet
package com.javastudy.servlet;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.javastudy.common.AppResult;
import com.javastudy.utils.UserUtils;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/**
* @author Chooker
* @create 2023-07-10 12:34
*/
@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {
ObjectMapper objectMapper = new ObjectMapper();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("application/json;charset=utf-8");
HttpSession session = req.getSession(false);
//判断session
if (UserUtils.checkUserLoginStatus(req) == null) {
//设置状态码 403 表示用户没有权限
resp.setStatus(403);
//错误描述
AppResult appResult = AppResult.fail("用户没有登录,请登录后再试");
//代表用户没有登录
resp.getWriter().write(objectMapper.writeValueAsString(appResult));
return;
}
if (session != null) {
session.invalidate();
}
resp.getWriter().write(objectMapper.writeValueAsString(AppResult.success("注销成功")));
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
7.测试登录功能
1.测试登录接口
1.配置tomcat
2.使用postman测试登录接口
1.用户名为空校验
符合代码的预期
2.用户名不存在校验
符合预期
3.密码错误校验
符合预期
4.正确登录校验
符合预期
2.测试用户接口
1.未登录状态
2.登录状态
3.测试博客接口
4.发布博客测试
发布博客成功.
8.导入前端页面
关于前段的html,css等信息可以到这个链接进行下载:
链接:https://pan.baidu.com/s/1BlLCsAzpN0szCsSEJYyF8Q?pwd=kvfu
提取码:kvfu
1.登录页面前端JS代码的实现
首先我们需要引入js的依赖
<script src="./js/jquery-3.6.3.min.js"></script>
<script>
//页面加载完成之后执行
jQuery(function () {
//为登录按钮绑定时间
jQuery("#btn_login_submit").click(function () {
//获取用户名
var username = jQuery("#username");
if (!username.val()) {
alert("用户名不能为空");
username.focus();
return;
}
//获取密码
var password = jQuery("#password");
if (!password.val()) {
alert("密码不能为空");
password.focus();
return;
}
//构造发送的数据
var postData = {
username: username.val(),
password: password.val()
};
jQuery.ajax({
type: 'get',
url: 'login',
contentType: 'application/x-www-form-urlencoded',
data: postData,
//表示正常发送 http200
success: function (respData) {
if (respData.code == 200) {
//登陆成功,跳转到blog_list.html
location.assign('blog_list.html');
} else {
//登陆失败
alert(respData.message);
}
},
//http不是200
error: function () {
console.log("访问出现问题");
}
});
})
})
</script>
注意点:记得将表单的属性全部去掉,可以仅仅当这是一个标签,不需要表单的提交,这样会整个页面刷新,我们使用的是AJAX的局部提交技术,可以将form标签改为div标签也可以
其次就是我们需要将按钮的属性从submit改为button,如果不修改的话,当我们点击按钮的时候自动提交给本页面,刷新本页面,之前填的信息都没有了,一次仅仅是一个button即可,之后通过绑定click事件进行相关的操作.
2.博客展示页面前端JS代码的实现
<script src="./js/jquery-3.6.3.min.js"></script>
<script src="./js/common.js"></script>
<script>
//页面加载完成之后执行
jQuery(function () {
//直接发送ajax请求,获取姓名
jQuery.ajax({
type: 'get',
url: 'user',
success: function (respData) {
if (respData.code == 0) {
//成功
var user = respData.data;
jQuery("#h_list_username").html(user.username);
} else {
//失败
}
},
error: function () {
console.log("访问出现问题");
},
statusCode: {
//可以为不同的HTTP状态码定义不同的方法
403: function () {
//打印日志并跳转到登录页面
console.log("用户无权访问");
location.assign('blog_login.html');
}
}
});
jQuery.ajax({
type: 'get',
url: 'blog',
//回调函数
success: function (respData) {
if (respData.code == 0) {
//构建文章列表
bulidArticleList(respData.data);
} else {
}
},
error: function () {
//打印日志
console.log("访问出现错误");
},
statusCode: {
403: function () {
//登陆失败
location.assign('blog_login.html');
}
}
});
jQuery("#a_list_logout").click(function () {
//发送请求
jQuery.ajax({
type: 'get',
url: 'logout',
//回调函数
success: function (respData) {
if (respData.code == 0) {
location.assign("blog_login.html");
} else {
alert(respData.message);
}
},
error: function () {
//打印日志
console.log("访问出现错误");
},
statusCode: {
403: function () {
//登陆失败
location.assign('blog_login.html');
}
}
});
});
})
function bulidArticleList(data) {
//如果data为空
if (!data || data.length == 0) {
var htmlString = "<h3>没有文章,懒狗快发布一篇</h3>";
jQuery(".container-right").html(htmlString);
return;
}
// for(var i=0;i<data.length;++i){
// var blog=data[i];
// }
data.forEach(element => {
var htmlStr = ' <div class="blog-content"> '
+ ' <div class="blog-title"> '
+ element.title
+ ' </div> '
+ ' <div class="blog-datetime"> '
+ formatDate(element.createTime)
+ ' </div> '
+ ' <div class="content"> '
+ element.content
+ ' </div> '
+ ' <div class="aEl"> '
+ ' <a href="./blog_details.html?blogId=' + element.id + '">查看全文 >> </a> '
+ ' </div> '
+ ' <hr> '
+ ' </div> ';
//追加到
jQuery(".container-right").append(htmlStr);
});
}
</script>
3.查看博客详细内容的js代码
<script src="./js/common.js"></script>
<script src="./js/jquery-3.6.3.min.js"></script>
<!-- 再引入编辑器插件 -->
<script src="./editor.md/editormd.min.js"></script>
<script src="./editor.md/lib/marked.min.js"></script>
<script src="./editor.md/lib/prettify.min.js"></script>
<script>
jQuery(function () {
//发送ajax请求,获取当前博客的详细信息
jQuery.ajax({
type: 'get',
url: 'blog' + location.search,
success: function (respData) {
if (respData.code == 0) {
var blog = respData.data;
//为页面中的相应标签进行赋值
jQuery("#div_details_title").html(blog.title);
jQuery("#div_details_datatime").html(formatDate(blog.createTime));
// jQuery('#div_detals_content').html(blog.content);
// 内容
editormd.markdownToHTML('div_details_content', { markdown: blog.content });
} else {
alert(respData.message);
}
},
error: function () {
console.log("访问出现错误");
},
statusCode: {
403: function () {
location.assign('blog_login.html');
}
}
});
//获取作者详情
jQuery.ajax({
type: 'get',
url: 'user' + location.search,
success: function (respData) {
if (respData.code == 0) {
var user = respData.data;
//设置作者名
jQuery("#h3_detail_author").html(user.username);
if (user.author) {
//生成删除按钮
var htmlStr = '<a href="javascript:void(0);">删除</a>';
//把HTML转换为jQuery对象并追加到当前页面
var deleteObj = jQuery(htmlStr);
//获取到按钮要追加元素的父标签
jQuery('.opts').append(deleteObj);
deleteObj.click(deleteBlog);
}
} else {
alert(respData.message);
}
},
error: function () {
console.log("访问出现错误");
},
statusCode: {
403: function () {
location.assign('blog_login.html');
}
}
});
//删除文章事件
function deleteBlog() {
if (!confirm("是否删除")) {
return;
}
jQuery.ajax({
type: 'delete',
url: 'blog' + location.search,
success: function (respData) {
if (respData.code == 0) {
location.assign('blog_list.html');
} else {
alert(respData.message);
}
},
error: function () {
console.log("访问出现错误");
},
statusCode: {
403: function () {
location.assign('blog_login.html');
}
}
});
}
})
</script>
4.编写发布博客的js代码
<!-- 先引入jQuery -->
<script src="./js/jquery-3.6.3.min.js"></script>
<!-- 再引入编辑器插件 -->
<script src="./editor.md/editormd.min.js"></script>
<!-- 初始化编辑器 -->
<script type="text/javascript">
$(function () {
var editor = editormd("blog_edit", {
width: "100%",
height: "100%",
// theme : "dark",
// previewTheme : "dark",
// editorTheme : "pastel-on-dark",
codeFold: true,
//syncScrolling : false,
saveHTMLToTextarea: true, // 保存 HTML 到 Textarea
searchReplace: true,
//watch : false, // 关闭实时预览
htmlDecode: "style,script,iframe|on*", // 开启 HTML 标签解析,为了安全性,默认不开启
// toolbar : false, //关闭工具栏
// previewCodeHighlight : false, // 关闭预览 HTML 的代码块高亮,默认开启
emoji: true,
taskList: true,
tocm: true, // Using [TOCM]
tex: true, // 开启科学公式TeX语言支持,默认关闭
flowChart: true, // 开启流程图支持,默认关闭
sequenceDiagram: true, // 开启时序/序列图支持,默认关闭,
placeholder: '开始创作...', // 占位符
path: "./editor.md/lib/"
});
jQuery("#submit").click(function () {
//获取用户数据
var titleEl = jQuery("#title");
if (!titleEl.val() || titleEl.val().length == 0) {
alert("请输入标题");
return;
}
var contentEl = jQuery("#text_edit_content");
if (!contentEl.val() || contentEl.val().length == 0) {
alert("请输入文章内容");
return;
}
//构造发送的数据
var postData = {
title: titleEl.val(),
content: contentEl.val()
}
//提交请求
jQuery.ajax({
type: 'post',
url: 'blog',
contentType: 'application/x-www-form-urlencoded',
data: postData,
success: function (respData) {
if(respData.code==0){
alert('发布成功');
location.assign('blog_list.html');
}else{
alert(respData.message);
}
},
error: function () {
console.log('访问出现错误');
},
statusCode: {
403: function () {
location.assign('blog_list.html');
}
}
})
})
});
</script>
三.部署并发布
1.购买服务器
购买服务器,可以从阿里云,腾讯云中购买服务器
选择centos
设置密码,购买即可
进入控制台,点击进入云服务器
点击即可进入服务器实例
2.配置服务器
通过xshell连接服务器,主机即为刚才买服务器的公网ip,只有有密码的验证,即为设置的自定义密码
登陆之后的页面
1.安装JDK
yum -y install java-1.8.0-openjdk.x86_64
注意:可通过Shift+insert复制到xshell中,有些笔记本电脑需要(Shift+Fn+insert)
通过以下命令验证是否安装成功,出现一下信息表示安装成功
java -version
2.安装数据库
安装mariadb服务
yum install -y mariadb-server
安装mariadb命令行客户端
yum install -y mariadb
安装mariadb C library
yum install -y mariadb-libs
安装mariadb开发包
yum install -y mariadb-devel
启动服务
systemctl start mariadb
设置服务开启自启动
systemctl enable mariadb
查看服务状态
systemctl status mariadb
active表示启动成功
安装成功之后可以正常连接服务器
语法与mysql一致
可以通过以下代码来进行设置密码和修改密码,默认没有密码
set password for 'root' @'localhost'=password('newpassword');
修改数据库的端口号:
vi /etc/my.cnf.d/server.cnf
重启数据库服务
systemctl restart mariadb
查看端口号:
show variables like 'port';
3.安装tomcat
通过,下面的命令下载拖拽工具
yum -y install lrzsz
直接将压缩包拖拽到命令行
安装解压工具
yum -y install unzip
解压压缩包
unzip apache-tomcat-8.5.47.zi
此时表示解压成功
进入到tomcat的bin目录下,启动tomcat
chmmod +x ./*.sh (因为没有执行权限,所以先改权限)
./startup.sh (启动)
通过以下命令查询状态
netstat -anp | grep 8080
进入控制台配置安全规则
防火墙设置
查看防火墙状态(如果没开启,建议开启,不开启可以直接访问,开启了需要进行已下的操作访问)
systemctl status firewalld
启动防火墙和关闭防火墙
systemctl start firewalld
systemctl stop firewalld
查看开放的端口号
firewall-cmd --list-ports
开启8080端口
firewall-cmd --permanent --add-port=8080/tcp
重启防火墙
firewall-cmd --reload
设置开机启动
systemctl enable firewalld
访问地址:公网ip:8080,看到以下的画面表示tomcat开启成功
3.部署发布
将项目打为war包,拖拽到tomcat的webapps目录下
创建数据库
两种方式:第一种我们可以一点点复制粘贴sql语句到数据库中,一步一步的执行
第二种,我们可以将sql语句写到一个文件中,然后拖拽到一个目录下,然后执行以下的语句
source /root/java78/create.sql
此时即可
注意:需要将项目war包里面的设置与linux服务器中的配置一样,比如数据库的信息之类的.