文章目录
- 效果展示
- 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(); @Override protected 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="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="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">查看全文>></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'; // 创建 title let h2 = document.createElement('h2'); h2.className = 'title'; h2.innerHTML = blog.title; blogDiv.appendChild(h2); // 创建 postTime let postTime = document.createElement('span'); postTime.className = 'date'; postTime.innerHTML = DateFormat(blog.postTime); blogDiv.appendChild(postTime); // 创建 content let 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 = '查看全文>>'; 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(); @Override protected 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="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="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. 更新 title let titleDiv = document.querySelector('.title'); titleDiv.innerHTML = blog.title; // 2. 更新 postTime let postTime = document.querySelector('.date'); postTime.innerHTML = DateFormat(blog.postTime); // 3 更新 content editormd.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 { @Override protected 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="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(); @Override protected 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 { @Override protected 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 { @Override protected 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="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 { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doDelete(req,resp); } @Override protected 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="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; @Override protected 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)); } @Override protected 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 { @Override protected 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(); @Override protected 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更改即可