博客系统(前后端分离)
创始人
2024-03-24 20:13:21
0

文章目录

  • 前言
  • 一、需求分析
    • 1.功能
    • 2.环境
  • 二、前端实现
    • 1.博客注册页
    • 2.博客登录页
    • 3.博客列表页
    • 4.博客详情页
    • 5.博客编辑页
  • 三、后端实现
    • 1.设计数据库表
    • 2.封装连接数据库的公共操作
    • 3.封装对博客表和用户表的操作
    • 4.实现博客列表页、博客详情页、博客编辑页的后端服务
    • 5.实现博客登录页面的后端服务
    • 6.实现博客删除的后端服务
    • 7.实现博客列表页中的用户信息和博客详情页中的作者信息
    • 8.实现博客注销功能的后端服务
    • 9.实现博客注册功能的后端服务
  • 四、部署到云服务器
    • 1.修改pom.xml
    • 2.修改DBUtil
    • 3.打包
    • 4.将包部署到终端上
    • 5.验证
  • 总结


前言

本篇文章根据前面学过的前端和后端知识,进行实践开发出一个个人的博客系统,这个博客系统主要可以进行查看博客、发布博客以及删除博客,最后部署到云服务器上可被他人所访问。


一、需求分析

1.功能

(1)注册
(2)登录
(3)查看所有博客列表
(4)查看某一篇博客
(5)编写博客并发布
(6)删除博客、注销博客。

2.环境

前端:html、css、js
后端:tomcat、servlet
部署:云服务器。

二、前端实现

1.博客注册页

在这里插入图片描述

我的博客系统
登录

注 册

用户名
密码

2.博客登录页

在这里插入图片描述

我的博客系统
主页写博客

登 录

用户名
密码

3.博客列表页

在这里插入图片描述

我的博客系统
主页写博客注销

github 地址
文章分类
21

4.博客详情页

在这里插入图片描述

我的博客系统
主页写博客注销删除

github 地址
文章分类
21

5.博客编辑页

在这里插入图片描述

我的博客系统
主页写博客注销

三、后端实现

1.设计数据库表

blog表:
blog(blogId,title,content,postTime,userId);
user表:
user(userId,userName,password);
在这里插入图片描述
在这里插入图片描述

2.封装连接数据库的公共操作

由于我们在进行博客的增删查改都需要连接数据库,所以我们对数据库的连接进行封装。
代码如下(示例):

public class DBUtil {private static volatile DataSource dataSource = null;private Connection connection = null;//将构造方法设为私有,防止不小心new出对象private DBUtil() {}//1.获取数据源public static DataSource getDataSource() {if (dataSource == null) {synchronized (DBUtil.class) {if (dataSource == null) {dataSource = new MysqlDataSource();((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/java105?characterEncoding=utf8&&useSSL=false");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("root");}}}return dataSource;}//2.建立连接public static Connection getConnection() throws SQLException {return getDataSource().getConnection();}//3.释放相关资源public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet) {if (resultSet != null) {try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}if (statement != null) {try {statement.close();} catch (SQLException e) {e.printStackTrace();}}if (connection != null) {try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}
}

3.封装对博客表和用户表的操作

(1)对数据库中的博客可以进行增删查的操作。
BlogDao:

public class BlogDao {//添加:插入一个博客到数据库中public void insert(Blog blog) {Connection connection = null;PreparedStatement statement = null;try {//1.获取数据源并连接connection = DBUtil.getConnection();//2.构造sql语句String sql = "insert into blog values(null,?,?,now(),?)";statement = connection.prepareStatement(sql);statement.setString(1, blog.getTitle());statement.setString(2,blog.getContent());statement.setInt(3,blog.getUserId());//3.执行sqlint ret = statement.executeUpdate();if (ret == 1) {System.out.println("博客插入成功!");}else {System.out.println("博客插入失败!");}} catch (SQLException e) {e.printStackTrace();} finally {//4.释放资源DBUtil.close(connection,statement,null);}}//查询:根据博客Id查询指定博客public Blog selectOne(int blogId) {Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try {//1.获取数据源并建立连接connection = DBUtil.getConnection();//2.构造SQLString sql = "select * from blog where blogId = ?";statement = connection.prepareStatement(sql);statement.setInt(1,blogId);//3.执行sqlresultSet = statement.executeQuery();if (resultSet.next()) {Blog blog = new Blog();blog.setBlogId(resultSet.getInt("blogId"));blog.setTitle(resultSet.getString("title"));blog.setContent(resultSet.getString("content"));blog.setPostTime(resultSet.getTimestamp("postTime"));blog.setUserId(resultSet.getInt("userId"));return blog;}} catch (SQLException e) {e.printStackTrace();} finally {//一定别忘记释放资源DBUtil.close(connection,statement,resultSet);}return null;}//查询:查询博客列表页的所有博客public List selectAll() {List blogs = new ArrayList<>();Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try {//1.获取数据源并建立连接connection = DBUtil.getConnection();//2.构造sqlString sql = "select * from blog";//3.执行sqlstatement = connection.prepareStatement(sql);//4.判读结果resultSet = statement.executeQuery();while (resultSet.next()) {Blog blog = new Blog();blog.setBlogId(resultSet.getInt("blogId"));blog.setTitle(resultSet.getString("title"));//列表页的博客只需要摘录正文一部分就好String content = resultSet.getString("content");if (content.length() > 100) {content = content.substring(0,100) + "......";}blog.setContent(content);blog.setPostTime(resultSet.getTimestamp("postTime"));blog.setUserId(resultSet.getInt("userId"));blogs.add(blog);}} catch (SQLException e) {e.printStackTrace();} finally {DBUtil.close(connection,statement,resultSet);}return blogs;}//删除:删除指定博客public void delete(int blogId) {Connection connection = null;PreparedStatement statement = null;try {connection = DBUtil.getConnection();String sql = "delete from blog where blogId=?";statement = connection.prepareStatement(sql);statement.setInt(1,blogId);int ret = statement.executeUpdate();if (ret == 1) {System.out.println("博客删除成功!");} else {System.out.println("博客删除失败!");}} catch (SQLException e) {e.printStackTrace();} finally {DBUtil.close(connection,statement,null);}}
}

(2)从用户表里面通过userId和userName进行查询的操作。
UserDao:

public class UserDao {//查询--by--用户名public User selectByName(String username) {Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try {//1.获取数据源并建立连接connection = DBUtil.getConnection();//2.构造sqlString sql = "select * from user where username=?";statement = connection.prepareStatement(sql);statement.setString(1,username);//3.执行sqlresultSet = statement.executeQuery();if (resultSet.next()) {User user = new User();user.setUserId(resultSet.getInt("userId"));user.setUserName(resultSet.getString("username"));user.setPassword(resultSet.getString("password"));return user;}} catch (SQLException e) {e.printStackTrace();} finally {DBUtil.close(connection,statement,resultSet);}return null;}//查询--by--用户IDpublic User selectById(int userId) {Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try {connection = DBUtil.getConnection();String sql = "select * from user where userId = ?";statement = connection.prepareStatement(sql);statement.setInt(1,userId);resultSet = statement.executeQuery();if (resultSet.next()) {User user = new User();user.setUserId(resultSet.getInt("userId"));user.setUserName(resultSet.getString("username"));user.setPassword(resultSet.getString("password"));return user;}} catch (SQLException e) {e.printStackTrace();} finally {DBUtil.close(connection,statement,resultSet);}return null;}//添加--添加新用户public void insert(User user) {Connection connection = null;PreparedStatement statement = null;try {//1.获取数据源并建立连接connection = DBUtil.getConnection();//2.构造sqlString sql = "insert into user values(null,?,?)";//3.执行sqlstatement = connection.prepareStatement(sql);statement.setString(1,user.getUsername());statement.setString(2,user.getPassword());int ret = statement.executeUpdate();//4.判断是否添加成功if (ret == 1) {System.out.println("新用户添加成功!");} else {System.out.println("新用户添加失败!");}} catch (SQLException e) {e.printStackTrace();} finally {DBUtil.close(connection,statement,null);}}
}

4.实现博客列表页、博客详情页、博客编辑页的后端服务

代码如下(示例):

@WebServlet("/blog")
public class BlogServlet extends HttpServlet {//可以使用ObjectMapper中的writeValueAsString和readValue两个方法ObjectMapper objectMapper = new ObjectMapper();@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//通过get请求实现blog_list和blog_detail的后端服务resp.setContentType("application/json; charset=utf-8");BlogDao blogDao = new BlogDao();//1.获取blogIdString blogId = req.getParameter("blogId");if (blogId == null) {//如果query string中没有blogId说明它是blog_list的请求//需要返回所有博客List blogs = blogDao.selectAll();resp.getWriter().write(objectMapper.writeValueAsString(blogs));} else {//如果不为null 则是blog_detail的请求//需要返回blogId这篇博客Blog blog = blogDao.selectOne(Integer.parseInt(blogId));resp.getWriter().write(objectMapper.writeValueAsString(blog));}}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//通过post请求实现用户提交博客的功能//1.获取当前会话HttpSession session = req.getSession(false);if (session == null) {resp.setStatus(403);resp.setContentType("text/html; charset=utf-8");resp.getWriter().write("当前未登录,发布失败");return;}User user = (User) session.getAttribute("user");if (user == null) {resp.setStatus(403);resp.setContentType("text/html; charset=utf-8");resp.getWriter().write("当前未登录,发布失败");return;}//2.得到请求中的参数req.setCharacterEncoding("utf8");String title = req.getParameter("title");String content = req.getParameter("content");//3.构造blog对象Blog blog = new Blog();blog.setTitle(title);blog.setContent(content);blog.setUserId(user.getUserId());//4.将blog对象插入数据库中BlogDao blogDao = new BlogDao();blogDao.insert(blog);//5.发布成功,重定向到列表页resp.sendRedirect("blog_list.html");}
}

5.实现博客登录页面的后端服务

实现登录功能的后端请求;
实现禁止未登录访问博客列表、博客详情页以及发布博客等功能(非法访问)。

代码如下(示例):

@WebServlet("/login")
public class LoginServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.从请求中获取用户名和密码req.setCharacterEncoding("utf8");String username = req.getParameter("username");String password = req.getParameter("password");//2.判断用户名或密码是否为空if (username == null || username.equals("") || password == null || password.equals("")) {//说明用户或者密码输入为空resp.setContentType("text/html; charset=utf8");resp.getWriter().write("用户名或密码为空!登录失败!");return;}//3.查询数据库,验证用户名和密码是否正确UserDao userDao = new UserDao();User user = userDao.selectByName(username);if (user == null || !user.getPassword().equals(password)) {//说明用户不存在resp.setContentType("text/html; charset=utf8");resp.getWriter().write("用户不存在或密码错误!登录失败!");return;}//4.正确,创建一个会话对象HttpSession session = req.getSession(true);session.setAttribute("user",user);//5.构造302响应报文resp.sendRedirect("blog_list.html");}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//判定当前登录状态//1.获取当前会话HttpSession session = req.getSession(false);//2.会话不存在,则403if (session == null) {resp.setStatus(403);return;}//3。会话存在,获取userUser user = (User) session.getAttribute("user");//4.判定用户是否存在if (user == null) {resp.setStatus(403);return;}//5.会话存在resp.setStatus(200);}
}

6.实现博客删除的后端服务

代码如下(示例):

@WebServlet("/blogDelete")
public class BlogDeleteServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.判定当前登录状态HttpSession session = req.getSession(false);if (session == null) {resp.setStatus(403);resp.setContentType("text/html; charset=utf8");resp.getWriter().write("当前用户未登录,不能删除");return;}User user = (User) session.getAttribute("user");if (user == null) {resp.setStatus(403);resp.setContentType("text/html; charset=utf8");resp.getWriter().write("当前用户未登录,不能删除");return;}//2.获取blogIdString blogId = req.getParameter("blogId");if (blogId == null) {resp.setStatus(403);resp.setContentType("text/html; charset=utf8");resp.getWriter().write("您当前删除的blogId有误!");return;}//3.查询blogId对应的blog对象BlogDao blogDao = new BlogDao();Blog blog = blogDao.selectOne(Integer.parseInt(blogId));if (blog == null) {resp.setStatus(403);resp.setContentType("text/html; charset=utf8");resp.getWriter().write("您当前删除的博客不存在!blogId="+blogId);return;}//4.判定登录用户是否就是当前作者if (blog.getUserId() != user.getUserId()) {resp.setStatus(403);resp.setContentType("text/html; charset=utf8");resp.getWriter().write("您不能删除其他人的博客!");return;}//5.真正执行删除blogDao.delete(Integer.parseInt(blogId));//6.重定向resp.sendRedirect("blog_list.html");}
}

7.实现博客列表页中的用户信息和博客详情页中的作者信息

代码如下(示例):

@WebServlet("/userInfo")
public class UserInfoServlet extends HttpServlet {ObjectMapper objectMapper = new ObjectMapper();@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.获取用户信息String blogId = req.getParameter("blogId");//2.判断query string 是否存在blogIdif (blogId == null) {//如果blogId不存在,则说明当前是blog_list页面//页面的左边框需要显示的是当前登录用户的信息--从session中获取getUserInfoFromSession(req,resp);} else {//如果blogId存在,则说明当前是blog_detail页面//页面的左边框需要显示的是当前博客作者的信息--从数据库中获取getUserInfoFromDB(req,resp,Integer.parseInt(blogId));}}private void getUserInfoFromDB(HttpServletRequest req, HttpServletResponse resp, int blogId) throws IOException {//1.先根据blogId查看blog对象,获取到博客的userIdBlogDao blogDao = new BlogDao();Blog blog = blogDao.selectOne(blogId);if (blog == null) {resp.setStatus(403);resp.setContentType("text/html; charset=utf-8");resp.getWriter().write("blogId不存在");return;}//2.根据userId查询对应的user对象UserDao userDao = new UserDao();User user = userDao.selectById(blog.getUserId());if (user == null) {resp.setStatus(403);resp.setContentType("text/html; charset=utf-8");resp.getWriter().write("blogId不存在");return;}//3.将用户返回给浏览器user.setPassword("");resp.setContentType("application/json; charset=utf-8");resp.getWriter().write(objectMapper.writeValueAsString(user));}private void getUserInfoFromSession(HttpServletRequest req, HttpServletResponse resp) throws IOException {//1.获取当前会话HttpSession session = req.getSession(false);//2.判断会话是否存在if (session == null) {//不存在则用户未登录resp.setStatus(403);resp.setContentType("text/html; charset=utf8");resp.getWriter().write("用户未登录");return;}//3.判断用户是否存在User user = (User) session.getAttribute("user");if (user == null) {//不存在则用户未登录resp.setStatus(403);resp.setContentType("text/html; charset=utf8");resp.getWriter().write("用户未登录");return;}//4.成功,将user返回user.setPassword("");resp.setContentType("application/json; charset=utf8");resp.getWriter().write(objectMapper.writeValueAsString(user));}
}

8.实现博客注销功能的后端服务

代码如下(示例):

@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {HttpSession session = req.getSession(false);if (session == null) {resp.setStatus(403);return;}session.removeAttribute("user");resp.sendRedirect("blog_login.html");}
}

9.实现博客注册功能的后端服务

代码如下(示例):

@WebServlet("/regist")
public class RegistServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.从请求中获取用户名和密码req.setCharacterEncoding("utf8");String username = req.getParameter("username");String password = req.getParameter("password");//2.判断用户名或密码是否为空if (username == null || username.equals("") || password == null || password.equals("")) {//用户名或密码输入为空resp.setContentType("text/html; charset=utf8");resp.getWriter().write("用户名或密码为空!注册失败!");return;}//3.查询数据库,看是否有相同用户名的用户UserDao userDao = new UserDao();User user = userDao.selectByName(username);if (user != null) {//说明数据库中有现在用户注册的用户名resp.setContentType("text/html; charset=utf8");resp.getWriter().write("用户名重复!注册失败!");return;}//4.真正的注册//向数据库中添加该注册用户user = new User();user.setUsername(username);user.setPassword(password);userDao.insert(user);//5.构造重定向resp.sendRedirect("blog_login.html");}
}

四、部署到云服务器

1.修改pom.xml

加上打包类型和打包后的包名。

    warblogSystem2

2.修改DBUtil

修改DBUtil中的数据库连接的URL、user、password保证和终端的一致。
在这里插入图片描述

3.打包

双击maven下的package进行打包。
在这里插入图片描述

4.将包部署到终端上

在这里插入图片描述

5.验证

可访问:http://121.4.74.140:8080/blogSystem2/blog_login.html

注:具体打包过程可以参考上一篇文章


总结

具体代码可以到我的gitee中下载。

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...