文章目录

  • 效果展示
  • 1. 创建 maven 项目
  • 2. 设计数据库
  • 3. 封装数据库的操作代码
    • 3.1 创建 DBUtil 类
    • 3.2 创建类 Blog (代表一篇博客)
    • 3.3 创建类 User (代表一个用户)
    • 3.4 创建类 BlogDao (对博客表进行操作)
    • 3.5 创建类 UserDao (对用户表进行操作)
  • 4. 导入之前写好的前端代码
  • 5. 实现博客主页界面
    • 5.1 约定好前后端交互接口
    • 5.2 实现 IndexServlet
    • 5.3 实现前端代码
  • 6. 实现博客详情界面
    • 6.1 约定好前后端交互接口
    • 6.2 实现 DetailsServlet
    • 6.3 实现前端代码
  • 7. 实现博客登录界面
    • 7.1 约定好前后端交互接口
    • 7.2 实现 LoginServlet
    • 7.3 实现前端代码
  • 8. 实现登录判定的功能
    • 8.1 创建一个 Common类 来判定当前登录状态
    • 8.2 在Sevlet代码中加入判定
    • 8.3 更改前端代码
  • 9. 实现显示用户信息的功能
    • 9.1 约定好前后端交互接口
    • 9.2 实现 UserServlet代码
    • 9.3 实现前端代码
  • 10. 实现注销功能
    • 10.1 约定好前后端交互接口
    • 10.2 实现 LogoutServlet
  • 11. 实现发布博客功能
    • 11.1 约定好前后端交互的接口
    • 11.2 实现 EditServlet
    • 11.3 更改前端代码
  • 12. 实现博客的删除功能
    • 12.1 约定好前后端交互接口
    • 12.2 在详情页中加入删除按钮
    • 12.3 添加 IsAuthor 字段到 Blog里
    • 12.4 更改 DetailsServlet中的代码
    • 12.5 更改 art.html 中的代码
    • 12.6 实现 DeleteServlet
  • 13. 实现对已完成的博客的修改功能
    • 13.1 约定好前后端交互的接口
    • 13.2 在详情页中加入删除按钮
    • 13.3 更改 art.html 中的代码
    • 13.4 实现编辑页(update.html)的前端代码
    • 13.5 实现 UpdateServlet
  • 14. 实现文章总数的展示功能
    • 14.1 约定好前后端交互的接口
    • 14.2 实现 TotalServlet
    • 14.3 更改前端代码
  • 15. 实现个人主页功能
    • 15.1 约定好前后端交互的接口
    • 15.2 实现 PersonServlet
    • 15.3 创建 person.html

效果展示




1. 创建 maven 项目

创建必要的目录.引入需要的依赖


2. 设计数据库

本系统要存入博客文章的信息,
创建博客表.博客的id,博客的标题,博客的内容,博客的日期,博文的博主id
也要存入用户的信息,
创建用户表,用户id,用户名,用户密码

create database if not exists MyBlogSystem;use MyBlogSystem;drop table if exists blog;-- 创建一个博客表
create table blog (blogId int primary key auto_increment,title varchar(1024),content mediumtext,postTime datetime,userId int
);drop table if exists user;-- 创建一个用户信息表
create table user (userId int primary key auto_increment,username varchar(128) unique,password varchar(128)
);

3. 封装数据库的操作代码

创建包Dao用来放数据库的代码.

3.1 创建 DBUtil 类

用来连接数据库

package Dao;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;public class DBUtil {private static final String URL = "jdbc:mysql://127.0.0.1:3306/MyBlogSystem?characterEncoding=utf8&useSSL=true&serverTimezone=UTC";private static final String USERNAME = "root";private static final String PASSWORD = "0000";private static volatile DataSource dataSource = null;private static DataSource getDataSource() {if(dataSource == null){synchronized(DBUtil.class){if(dataSource == null){dataSource = new MysqlDataSource();((MysqlDataSource) dataSource).setURL(URL);((MysqlDataSource) dataSource).setUser(USERNAME);((MysqlDataSource) dataSource).setPassword(PASSWORD);}}}return dataSource;}public static Connection getConnection() throws SQLException {return getDataSource().getConnection();}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.2 创建类 Blog (代表一篇博客)

Blog

package Dao;import java.sql.Timestamp;public class Blog {public int blogId;public String title;public String content;public Timestamp postTime;public int userId;public int getBlogId() {return blogId;}public void setBlogId(int blogId) {this.blogId = blogId;}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 getPostTime() {return postTime;}public void setPostTime(Timestamp postTime) {this.postTime = postTime;}public int getUserId() {return userId;}public void setUserId(int userId) {this.userId = userId;}
}

3.3 创建类 User (代表一个用户)

package Dao;public class User {public int userId;public String username;public String password;public int getUserId() {return userId;}public void setUserId(int userId) {this.userId = userId;}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;}
}

3.4 创建类 BlogDao (对博客表进行操作)

package Dao;import java.sql.*;
import java.util.ArrayList;
import java.util.List;public class BlogDao {// 1. 插入一篇博客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,?,?,?,?)";statement = connection.prepareStatement(sql);statement.setString(1,blog.getTitle());statement.setString(2,blog.getContent());statement.setTimestamp(3,blog.getPostTime());statement.setInt(4,blog.getUserId());// 3. 执行 SQL 语句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. 获取全部博客public List<Blog> selectAll() {Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;List<Blog> list = new ArrayList<>();try {// 1. 建立连接connection = DBUtil.getConnection();// 2. 拼装 SQL 语句// 这里加上order by postTime desc 就可以根据时间排序了.String sql = "select * from blog order by postTime desc ";statement = connection.prepareStatement(sql);// 3. 执行 SQL 语句resultSet = statement.executeQuery();// 4. 遍历结果集while (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"));list.add(blog);}} catch (SQLException e) {e.printStackTrace();} finally {DBUtil.close(connection,statement,resultSet);}return list;}// 3. 获取个人博客public List<Blog> selectAllPerson(int userId){Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;List<Blog> list = new ArrayList<>();try {// 1. 建立连接connection = DBUtil.getConnection();// 2. 拼装 SQL 语句// 这里加上order by postTime desc 就可以根据时间排序了.String sql = "select * from blog where userId = ? order by postTime desc ";statement = connection.prepareStatement(sql);statement.setInt(1,userId);// 3. 执行 SQL 语句resultSet = statement.executeQuery();// 4. 遍历结果集while (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"));list.add(blog);}} catch (SQLException e) {e.printStackTrace();} finally {DBUtil.close(connection,statement,resultSet);}return list;}// 4. 根据文章id获取指定博客public Blog selectOne(int blogId) {Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try {// 1. 建立连接connection = DBUtil.getConnection();// 2. 拼装 SQL 语句// 这里加上order by postTime desc 就可以根据时间排序了.String sql = "select * from blog where blogId = ? ";statement = connection.prepareStatement(sql);statement.setInt(1,blogId);// 3. 执行 SQL 语句resultSet = statement.executeQuery();// 4. 遍历结果集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;}// 5. 删除指定文章id的博客public void delete(int blogId) {Connection connection = null;PreparedStatement statement = null;try {// 1. 建立连接connection = DBUtil.getConnection();// 2. 拼装 SQL 语句String sql = "delete from blog where blogId = ?";statement = connection.prepareStatement(sql);statement.setInt(1,blogId);// 3. 执行 SQL 语句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);}}// 6. 计算个人文章的总数public Integer selectTotal(int userId) {Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try {// 1. 建立连接connection = DBUtil.getConnection();// 2. 拼装 SQL 语句String sql = "select count(userId) from blog where userId = ?";statement = connection.prepareStatement(sql);statement.setInt(1,userId);// 3. 执行 SQL 语句resultSet = statement.executeQuery();// 4. 遍历结果集if (resultSet.next()){return resultSet.getInt("count(userId)");}} catch (SQLException e) {e.printStackTrace();} finally {DBUtil.close(connection,statement,resultSet);}return null;}public static void main(String[] args) {BlogDao blogDao = new BlogDao();Blog blog = new Blog();blog.setContent("你好");blog.setTitle("你好");blog.setUserId(1);blog.setPostTime(new Timestamp(System.currentTimeMillis()));blogDao.insert(blog);System.out.println(blogDao.selectAll());}
}

3.5 创建类 UserDao (对用户表进行操作)

package Dao;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class UserDao {// 注册账号public void insert(User user){Connection connection = null;PreparedStatement statement = null;try {// 1. 建立连接connection = DBUtil.getConnection();// 2. 拼装 SQL 语句String sql = "insert into user values (null,?,?)";statement = connection.prepareStatement(sql);statement.setString(1,user.getUserName());statement.setString(2, user.getPassWord());// 3. 执行 SQL 语句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);}}// 通过用户名查找public User selectByName(String username){Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try {// 1. 建立连接connection = DBUtil.getConnection();// 2. 拼装 SQL 语句String sql = "select * from user where username = ?";statement = connection.prepareStatement(sql);statement.setString(1,username);// 3. 执行 SQL 语句resultSet = statement.executeQuery();// 4. 查找结果集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;}// 通过用户id查找public User selectById(int userId){Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try {// 1. 建立连接connection = DBUtil.getConnection();// 2. 拼装 SQL 语句String sql = "select * from user where userId = ?";statement = connection.prepareStatement(sql);statement.setInt(1,userId);// 3. 执行 SQL 语句resultSet = statement.executeQuery();// 4. 遍历结果集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;}
}

4. 导入之前写好的前端代码

5. 实现博客主页界面

5.1 约定好前后端交互接口

5.2 实现 IndexServlet

package api;import Dao.Blog;
import Dao.BlogDao;
import com.fasterxml.jackson.databind.ObjectMapper;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 java.io.IOException;
import java.util.List;@WebServlet("/index")
public class HomeServlet extends HttpServlet {private ObjectMapper objectMapper = new ObjectMapper();@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("application/json;charset=utf8");BlogDao blogDao = new BlogDao();List<Blog> blogs = blogDao.selectAll();String jsonString = objectMapper.writeValueAsString(blogs);resp.getWriter().write(jsonString);}
}

5.3 实现前端代码

注意: 这里传过来的时间,是毫秒级别,需要转换成格式化日期

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><link rel="stylesheet" href="css/list.css"><link rel="stylesheet" href="css/common.css">
</head>
<body><div class="nav"><img src="data:image/2.png" alt="头像"><span class="title">我的博客系统</span><a href="home.html">主页</a><a href="edit.html">创作</a><a href="login.html">注销</a></div><div class="parent"><div class="left"><div class="card"><img src="data:image/头像.jpg"><span class="name">蜡笔小新</span><a href="#">github 地址</a><div class='one'><span>文章</span><span>分类</span></div><div class='one'><span>2</span><span>1</span></div></div></div><div class="right"><!-- <div class="article"><h2 class="title">我的第一篇博客</h2><span class="date">2022-4-17</span><div class="desc">今天开始我要认真写博客 Lorem ipsum dolor sit amet consectetur adipisicing elit. Tempore similique, nobis labore, officiis harum vel amet iste enim, cupiditate eveniet dolores optio eligendi in dicta veniam obcaecati rerum voluptas ipsum.</div><a href="art.html" class="more">查看全文&gt;&gt;</a></div> --></div></div><script src="js/jquery.min.js"></script><script>// 1. 通过 ajax 来给服务器发送获取博客的请求$.ajax({url: 'index',method: 'GET',success: function(data,status) {buildBlogs(data);}})// 2. 根据响应中的 body 数据,构造HTML内容function buildBlogs(blogs){let rightDiv = document.querySelector('.right');for(let blog of blogs){let blogDiv = document.createElement('div');blogDiv.className = 'article';// 创建 titlelet h2 = document.createElement('h2');h2.className = 'title';h2.innerHTML = blog.title;blogDiv.appendChild(h2);// 创建 postTimelet postTime = document.createElement('span');postTime.className = 'date';postTime.innerHTML = DateFormat(blog.postTime);blogDiv.appendChild(postTime);// 创建 contentlet content = document.createElement('div');content.className = 'desc';content.innerHTML = blog.content;blogDiv.appendChild(content);// 创建 详情页的超链接let detailA = document.createElement('a');detailA.className = 'more';detailA.href = 'art.html?blogId=' + blog.blogId;detailA.innerHTML = '查看全文&gt;&gt;';blogDiv.appendChild(detailA);// 加入到 right 中rightDiv.appendChild(blogDiv);}}// 把毫秒级时间戳转化成格式化日期function DateFormat(timeStampMS) {var date = new Date(timeStampMS);var year = date.getFullYear(),month = date.getMonth()+1,//月份是从0开始的day = date.getDate(),hour = date.getHours(),min = date.getMinutes(),sec = date.getSeconds();var newTime = year + '-' +(month < 10? '0' + month : month) + '-' +(day < 10? '0' + day : day) + ' ' +(hour < 10? '0' + hour : hour) + ':' +(min < 10? '0' + min : min) + ':' +(sec < 10? '0' + sec : sec);return newTime;}</script>
</body>
</html>

6. 实现博客详情界面

6.1 约定好前后端交互接口

6.2 实现 DetailsServlet

package api;import Dao.Blog;
import Dao.BlogDao;
import com.fasterxml.jackson.databind.ObjectMapper;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 java.io.IOException;@WebServlet("/details")
public class DetailsServlet extends HttpServlet {private ObjectMapper objectMapper = new ObjectMapper();@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("application/json;charset=utf8");String blogId = req.getParameter("blogId");BlogDao blogDao = new BlogDao();Blog blog = blogDao.selectOne(Integer.parseInt(blogId));resp.getWriter().write(objectMapper.writeValueAsString(blog));}
}

6.3 实现前端代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><link rel="stylesheet" href="css/moreList.css"><link rel="stylesheet" href="css/common.css"><!-- 引入 editor.md 的依赖 --><link rel="stylesheet" href="editor.md/css/editormd.min.css" /><script src="js/jquery.min.js"></script><script src="editor.md/lib/marked.min.js"></script><script src="editor.md/lib/prettify.min.js"></script><script src="editor.md/editormd.js"></script>
</head>
<body><div class="nav"><img src="data:image/2.png" alt="头像"><span class="title">我的博客系统</span><a href="home.html">主页</a><a href="edit.html">创作</a><a href="login.html">注销</a></div><div class="parent"><div class="left"><div class="card"><img src="data:image/头像.jpg"><span class="name">蜡笔小新</span><a href="#">github 地址</a><div class='one'><span>文章</span><span>分类</span></div><div class='one'><span>2</span><span>1</span></div></div></div><div class="right"> <div class="article"><h2 class="title">我的第一篇博客</h2><span class="date">2022-4-17</span><div class="desc" id="content" style="background-color: transparent;"></div></div> </div></div><script src="js/jquery.min.js"></script><script>$.ajax({method: 'GET',url: 'details' + location.search,success: function(data,status){buildBlog(data);}});function buildBlog(blog){// 1. 更新 titlelet titleDiv = document.querySelector('.title');titleDiv.innerHTML = blog.title;// 2. 更新 postTimelet postTime = document.querySelector('.date');postTime.innerHTML = DateFormat(blog.postTime);// 3 更新 contenteditormd.markdownToHTML('content', {markdown: blog.content});}// 把毫秒级时间戳转化成格式化日期function DateFormat(timeStampMS) {var date = new Date(timeStampMS);var year = date.getFullYear(),month = date.getMonth()+1,//月份是从0开始的day = date.getDate(),hour = date.getHours(),min = date.getMinutes(),sec = date.getSeconds();var newTime = year + '-' +(month < 10? '0' + month : month) + '-' +(day < 10? '0' + day : day) + ' ' +(hour < 10? '0' + hour : hour) + ':' +(min < 10? '0' + min : min) + ':' +(sec < 10? '0' + sec : sec);return newTime;}</script>
</body>
</html>

7. 实现博客登录界面

7.1 约定好前后端交互接口

7.2 实现 LoginServlet

package api;import Dao.User;
import Dao.UserDao;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;@WebServlet("/login")
public class LoginServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html;charset=utf-8");// 获取账户密码String username = req.getParameter("username");String password = req.getParameter("password");if(username == null || "".equals(username) || password == null || "".equals(password)){resp.getWriter().write("<script>alert('用户名密码不能为空!')</script>");return;}UserDao userDao = new UserDao();User user = userDao.selectByName(username);if(user == null){resp.getWriter().write("<script>alert('用户不存在!')</script>");return;}if(!password.equals(user.getPassWord())){resp.getWriter().write("<script>alert('用户名密码错误!')</script>");return;}HttpSession session = req.getSession(true);session.setAttribute("user",user);resp.sendRedirect("home.html");}
}

7.3 实现前端代码

这里只需要设置form标签就可以了

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><link rel="stylesheet" href="css/common.css"><link rel="stylesheet" href="css/login.css">
</head>
<body><div class="nav"><img src="data:image/2.png" alt="头像"><span class="title1">我的博客系统</span><a href="home.html">主页</a><a href="edit.html">创作</a><a href="login.html">注册</a></div><div id="one"><div class="login"><form action="login" method="post"> <div class="text">个人博客系统</div><div class="one"><span class="name">用户名</span><input type="text" class="user"  name="username"></div><div class="one"><span class="name">密码</span><input type="password" class="password" name="password"></div><div class="submit"><input type="submit" class="button" value="登 录"></div></form> </div></div>
</body>
</html>

8. 实现登录判定的功能

8.1 创建一个 Common类 来判定当前登录状态

package common;import Dao.User;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;public class Common {public static User checkLoginStatus (HttpServletRequest req){// 判断是否登录了. 如果能够拿到 Session, 并且拿到 Session 里的 user对象,就认为是登录状态HttpSession session = req.getSession(false);if(session == null){// 没有登录的情况return null;}User user = (User) session.getAttribute("user");return user;}}

8.2 在Sevlet代码中加入判定

如果当前没有登录,就返回一个403的状态码

这段代码加入到 IndexServlet 和 DetailsServlet 中

        User user = Common.checkLoginStatus(req);if (user == null){resp.setStatus(403);return;}

8.3 更改前端代码

由于返回的是403 没有执行ajax中的success.而是执行的另一个方法.叫error
 
注意这里的重定向是使用 location.assign("login.html");

这里的代码写入 home.html 和 art.html中

$.ajax({url: 'index',method: 'GET',success: function(data,status) {buildBlogs(data);},error: function(data,status) {// 这个就是前端的重定向location.assign('login.html');}})

9. 实现显示用户信息的功能

9.1 约定好前后端交互接口

9.2 实现 UserServlet代码

package api;import Dao.Blog;
import Dao.BlogDao;
import Dao.User;
import Dao.UserDao;
import com.fasterxml.jackson.databind.ObjectMapper;
import common.Common;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 java.io.IOException;@WebServlet("/user")
public class UserServlet extends HttpServlet {private ObjectMapper objectMapper = new ObjectMapper();@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("application/json;charset=utf8");User user = Common.checkLoginStatus(req);// 没登录的情况if(user == null){resp.setContentType("text/html;charset=utf-8");resp.getWriter().write("<script>alert('当前用户未登录')</script>");return;}String blogId = req.getParameter("blogId");if(blogId == null){// 这里是主页界面String jsonString = objectMapper.writeValueAsString(user);resp.getWriter().write(jsonString);}else{// 这是详情页界面BlogDao blogDao = new BlogDao();Blog blog = blogDao.selectOne(Integer.parseInt(blogId));if (blog == null){resp.setContentType("text/html;charset=utf-8");resp.getWriter().write("<script>alert('当前用户未登录')</script>");return;}UserDao userDao = new UserDao();User author = userDao.selectById(blog.getUserId());String jsonString = objectMapper.writeValueAsString(author);resp.getWriter().write(jsonString);}}
}

9.3 实现前端代码

在之前的 home.html中添加以下代码

        $.ajax({url: 'user',method: 'get',success: function(data,status){changeUser(data);}});function changeUser(user) {let name = document.querySelector('.left>.card>.name');name.innerHTML = user.username;}

在之前的 art.html中添加以下代码

        $.ajax({url: 'user'+location.search,method: 'get',success: function(data,status){changeUser(data);}});function changeUser(user) {let name = document.querySelector('.left>.card>.name');name.innerHTML = user.username;}

10. 实现注销功能

10.1 约定好前后端交互接口

10.2 实现 LogoutServlet

注意修改:前端代码中的 注销的href为logout

package api;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;@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html;charset=utf-8");HttpSession session = req.getSession(false);if(session == null){resp.getWriter().write("<script>alert('当前用户未登录')</script>");return;}session.removeAttribute("user");resp.sendRedirect("login.html");}
}

11. 实现发布博客功能

11.1 约定好前后端交互的接口

11.2 实现 EditServlet

package api;import Dao.Blog;
import Dao.BlogDao;
import Dao.User;
import common.Common;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 java.io.IOException;
import java.sql.Timestamp;@WebServlet("/edit")
public class EditServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("utf-8");resp.setContentType("text/html;charset=utf-8");User user = Common.checkLoginStatus(req);if (user == null){resp.sendRedirect("login.html");return;}String title = req.getParameter("title");String content = req.getParameter("content");if(title == null || "".equals(title) || content == null || "".equals(content)){resp.getWriter().write("<script>alert('有内容为空')</script>");return;}BlogDao blogDao = new BlogDao();Blog blog = new Blog();blog.setContent(content);blog.setPostTime(new Timestamp(System.currentTimeMillis()));blog.setTitle(title);blog.setUserId(user.getUserId());blogDao.insert(blog);resp.sendRedirect("home.html");}
}

11.3 更改前端代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><link rel="stylesheet" href="css/common.css"><link rel="stylesheet" href="css/edit.css"><!-- 引入 editor.md 的依赖 --><link rel="stylesheet" href="editor.md/css/editormd.min.css" /><script src="js/jquery.min.js"></script><script src="editor.md/lib/marked.min.js"></script><script src="editor.md/lib/prettify.min.js"></script><script src="editor.md/editormd.js"></script>
</head>
<body><div class="nav"><img src="data:image/2.png" alt="头像"><span class="title1">我的博客系统</span><a href="home.html">主页</a><a href="edit.html">创作</a><a href="logout">注销</a></div><div class="leader"><form action="edit" method="post" style="height: 100%;"><div class="empOne"><input type="text" class="title" value="在这里写下文章标题" onblur="if(this.value == '')this.value='在这里写下文章标题';" onclick="if(this.value == '在这里写下文章标题')this.value='';" name="title"><input type="submit" value="发布文章" class="publish"></div><div id="editor"><textarea name="content" style="display: none;"></textarea></div></form></div><script>// 初始化编辑器var editor = editormd("editor", {// 这里的尺寸必须在这里设置. 设置样式会被 editormd 自动覆盖掉.width: "100%",// 高度 100% 意思是和父元素一样高. 要在父元素的基础上去掉标题编辑区的高度height: "calc(100% - 75px)",// 编辑器中的初始内容markdown: "# 在这里写下一篇博客",// 指定 editor.md 依赖的插件路径path: "editor.md/lib/",// 放到 textarea中saveHTMLToTextArea: true});</script></body>
</html>

12. 实现博客的删除功能

12.1 约定好前后端交互接口

12.2 在详情页中加入删除按钮

#make {margin: 5px;display: block;text-align: center;}
#make a{color:black;text-decoration: none;}
#make a:hover{background-color: rgba(206, 144, 64, 0.8);
}

12.3 添加 IsAuthor 字段到 Blog里

12.4 更改 DetailsServlet中的代码

12.5 更改 art.html 中的代码

12.6 实现 DeleteServlet

package api;import Dao.BlogDao;
import Dao.User;
import common.Common;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 java.io.IOException;@WebServlet("/delete")
public class DeleteServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doDelete(req,resp);}@Overrideprotected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {User user = Common.checkLoginStatus(req);if(user == null){resp.getWriter().write("<script>alert('当前未登录')</script>");return;}String blogId = req.getParameter("blogId");if(blogId == null || "".equals(blogId)){resp.getWriter().write("<script>alert('blogId丢失')</script>");return;}BlogDao blogDao = new BlogDao();blogDao.delete(Integer.parseInt(blogId));resp.sendRedirect("home.html");}
}

13. 实现对已完成的博客的修改功能

13.1 约定好前后端交互的接口

13.2 在详情页中加入删除按钮

在上一步的delete中添加即可

13.3 更改 art.html 中的代码

13.4 实现编辑页(update.html)的前端代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><link rel="stylesheet" href="css/common.css"><link rel="stylesheet" href="css/edit.css"><!-- 引入 editor.md 的依赖 --><link rel="stylesheet" href="editor.md/css/editormd.min.css" /><script src="js/jquery.min.js"></script><script src="editor.md/lib/marked.min.js"></script><script src="editor.md/lib/prettify.min.js"></script><script src="editor.md/editormd.js"></script>
</head>
<body><div class="nav"><img src="data:image/2.png" alt="头像"><span class="title1">我的博客系统</span><a href="home.html">主页</a><a href="edit.html">创作</a><a href="logout">注销</a></div><div class="leader"><form action="update" method="post" style="height: 100%;"><div class="empOne"><input type="text" class="title" name="title"><input type="submit" value="发布文章" class="publish"></div><div id="editor"><textarea name="content" id="content" style="display: none;"></textarea></div></form></div><script>var content;$.ajax({url: 'update' + location.search,method: 'get',success: function(data,status){changeEdit(data);}});function changeEdit(blog){let title = document.querySelector('.empOne>.title');title.value = blog.title;let content = document.querySelector('#content');content.innerHTML = blog.content;}// 初始化编辑器var editor = editormd("editor", {// 这里的尺寸必须在这里设置. 设置样式会被 editormd 自动覆盖掉.width: "100%",// 高度 100% 意思是和父元素一样高. 要在父元素的基础上去掉标题编辑区的高度height: "calc(100% - 75px)",// 指定 editor.md 依赖的插件路径path: "editor.md/lib/",// 放到 textarea中saveHTMLToTextArea: true});</script></body>
</html>

13.5 实现 UpdateServlet

doget 方法是显示编辑页面
dopost 方法是提交修改后的文章

package api;import Dao.Blog;
import Dao.BlogDao;
import Dao.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import common.Common;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 java.io.IOException;
import java.sql.Timestamp;@WebServlet("/update")
public class UpdateServlet extends HttpServlet {private ObjectMapper objectMapper = new ObjectMapper();private int BlogId = 0;@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("application/json;charset=utf-8");User user = Common.checkLoginStatus(req);if(user == null){resp.setContentType("text/html;charset=utf-8");resp.getWriter().write("<script>alert('当前未登录')</script>");return;}String blogId = req.getParameter("blogId");if(blogId == null || "".equals(blogId)){resp.setContentType("text/html;charset=utf-8");resp.getWriter().write("<script>alert('blogId丢失')</script>");}BlogId = Integer.parseInt(blogId);BlogDao blogDao = new BlogDao();Blog blog = blogDao.selectOne(Integer.parseInt(blogId));resp.getWriter().write(objectMapper.writeValueAsString(blog));}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("utf-8");resp.setContentType("application/json;charset=utf8");User user = Common.checkLoginStatus(req);if(user == null){resp.setContentType("text/html;charset=utf-8");resp.getWriter().write("<script>alert('当前未登录')</script>");return;}String title = req.getParameter("title");String content = req.getParameter("content");if(title == null || "".equals(title) || content == null || "".equals(content)){resp.getWriter().write("<script>alert('有内容为空')</script>");return;}int blogId = BlogId;BlogDao blogDao = new BlogDao();Blog blog = new Blog();blog.setPostTime(new Timestamp(System.currentTimeMillis()));blog.setTitle(title);blog.setContent(content);blog.setBlogId(blogId);blogDao.update(blog);resp.sendRedirect("home.html");}
}

14. 实现文章总数的展示功能

14.1 约定好前后端交互的接口

14.2 实现 TotalServlet

package api;import Dao.Blog;
import Dao.BlogDao;
import Dao.User;
import Dao.UserDao;
import common.Common;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 java.io.IOException;@WebServlet("/num")
public class TotalServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("text/html;charset=utf-8");String blogId = req.getParameter("blogId");User user = Common.checkLoginStatus(req);// 没登录的情况if(user == null){resp.setContentType("text/html;charset=utf-8");resp.getWriter().write("<script>alert('当前用户未登录')</script>");return;}BlogDao blogDao = new BlogDao();if(blogId == null){resp.getWriter().write(blogDao.selectTotal(user.getUserId())+"");}else {Blog blog = blogDao.selectOne(Integer.parseInt(blogId));UserDao userDao = new UserDao();User author = userDao.selectById(blog.getUserId());resp.getWriter().write(blogDao.selectTotal(author.getUserId())+"");}}
}

14.3 更改前端代码

在art.html中添加

        $.ajax({url: 'num'+location.search,method: 'get',success: function(data,status){changeNum(data);}});function changeNum(total){let num = document.querySelector('.total');num.innerHTML = total;console.log(total);}

在 home.html中添加

        $.ajax({url: 'num',method: 'get',success: function(data,status){changeNum(data);}});function changeNum(total){let num = document.querySelector('.total');num.innerHTML = total;console.log(total);}

15. 实现个人主页功能

15.1 约定好前后端交互的接口

15.2 实现 PersonServlet

package api;import Dao.Blog;
import Dao.BlogDao;
import Dao.User;
import com.fasterxml.jackson.databind.ObjectMapper;
import common.Common;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 java.io.IOException;
import java.util.List;@WebServlet("/person")
public class PersonServlet extends HttpServlet {private ObjectMapper objectMapper = new ObjectMapper();@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.setContentType("application/json;charset=utf8");User user = Common.checkLoginStatus(req);if (user == null){resp.setStatus(403);return;}BlogDao blogDao = new BlogDao();List<Blog> blogs = blogDao.selectAllPerson(user.getUserId());String jsonString = objectMapper.writeValueAsString(blogs);resp.getWriter().write(jsonString);}
}

15.3 创建 person.html

这里只需要把homt.html中的 method更改即可

JavaWeb 项目 --- 博客系统(前后分离)相关推荐

  1. JavaWeb项目——博客系统

    系统介绍 博客是互联网平台上的个人信息交流中心.通常博客就是用来发表文章,所有的文章都是按照年份和日期排列,有些类似斑竹的日记.看上去平淡无奇,毫无可炫耀之处,但它可以让每个人零成本.零维护地创建自己 ...

  2. JavaWeb 项目 --- 博客系统(基于模板引擎)

    文章目录 1. 创建 maven 项目 2. 设计数据库 3. 封装数据库的操作代码 3.1 创建 DBUtil 类 3.2 创建类 Blog (代表一篇博客) 3.3 创建类 User (代表一个用 ...

  3. 从零开始开发SSM项目-博客系统实战

    一.项目包含功能 使用SSM框架开发一个博客系统,包含的功能大致有: 1.用户注册与激活,激活方式通过邮件激活 2.用户的登录和退出,包括账号登录.手机快捷登录和qq第三方登录 3.用户账号登录和注册 ...

  4. 前端页面项目——博客系统

    目录 1.实现博客列表页 1.1 实现导航栏 1.2 实现中间版心 1.3 实现个人信息 1.4 实现博客列表 2. 实现博客正文页 3. 实现博客登陆页 4. 实现博客编辑 4.1 实现编辑区 4. ...

  5. 前端项目 - 博客系统(纯页面)

    预览效果 1. 实现博客列表页 导航栏 common.css blog_list.html blog_list.css 2. 实现博客正文页 blog_detail.html blog_detail. ...

  6. SSM项目 - 博客系统

    在线体验 : http://43.139.1.94:8080/login.html 项目 Gitee 链接 : 博客系统 - SSM 1.SSM 版本的博客系统相较于 Servlet 版本的升级 1. ...

  7. Java项目——博客系统(毕业设计)

    文末获取资源 文章目录 主页 注册模块 个人中心模块 发布文章模块 推荐模块 评论模块 点赞模块 通知模块 主页 主页是用户打开的第一个页面,是到达各个模块的入口,友好的一个界面可以给用户一个好的印象 ...

  8. 基于Spring+SpringMVC+MyBatis博客系统的开发教程(十三)

    第13课:第三方 QQ 登录及账号绑定与解除 使用 QQ 第三方登录时要调用第三方接口,需要 AppID 和 AppKey 等信息,所以首先要申请注册一下. 申请注册 首先在百度搜索 QQ 互联或者点 ...

  9. Java项目:朴素风个人博客系统(前后端分离+java+vue+Springboot+ssm+mysql+maven+redis)

    源码获取:博客首页 "资源" 里下载! 一.项目简述 本系统功能包括: 基于vue + Springboo痼J后端分离项目个人博客系统,注册 登录,首页展示,喜爰图书展示,后台图书 ...

最新文章

  1. VS如何更改项目类型?
  2. Vue中使用html2canvas和jspdf插件实现导出pdf(自定义html样式可带图片)并下载
  3. 爬虫那些事儿-- 简介
  4. ubuntu 如何卸载qt_UBuntu14.04下安装和卸载Qt5.3.1
  5. mysql配置文件my.cnf详解
  6. Oracle DataGuard 之--Physical DG转换Logical DG
  7. JAVA中为什么要用接口定义编程_【Java公开课|为什么要用Java接口,这些内容你一定要搞清楚】- 环球网校...
  8. dom4j解析xml获取所有的子节点并放入map中
  9. 如何实现一个php框架系列文章【2】实现类的自动加载
  10. 云台球型摄像机市场深度研究分析报告
  11. JavaWeb项目间隔刷新出现412
  12. Luogu P3110 [USACO14DEC]驮运Piggy Back
  13. 《紫川》之远东战火 十二卷
  14. 标题:史丰收速算 史丰收速算法的革命性贡献是:从高位算起,预测进位。不需要九九表,彻底颠覆了传统手算! 速算的核心基础是:1位数乘以多位数的乘法。 其中,乘以7是最复杂
  15. swift学习之旅之 iOS Flurry使用
  16. 微信小程序 三角形实现 (评论三角形)
  17. 插件目标[置顶] Maven自定义绑定
  18. 【css】使用 canvas 画一个圆、贝塞尔曲线画对话气泡
  19. 黑镜成真!3分钟看懂马斯克直播脑机接口,芯片植入猪脑,活猪演示
  20. 使用Microsoft Office Publisher制作海报Poster

热门文章

  1. 一种基于视神经网络的高动态范围(HDR)图像自适应局部色调映射的实现【OpenCV】【CUDA】
  2. 1129. 颜色交替的最短路径
  3. 5分钟商学院-个人篇-领导能力
  4. java properties读取中文_Java读取properties文件中文乱码
  5. android7.0模拟器调试,android - 为什么在android 7.0及更高版本上出现模拟器错误? - 堆栈内存溢出...
  6. ios版android wear下载,iPhone能用Android Wear?新版本全面对iOS兼容
  7. c语言中null和空格的区别,空字符串(“”)和null和空格字符串( )的区别
  8. 九章算法-面试题总结(算法、强化算法、系统设计高清视频观看)
  9. int、long int 和 long long int 的取值范围
  10. 创新案例分享 | 构建高效、智能人力管理系统,助力公司战略转型