一、博客系统简介
现进行登录确认身份,登录成功后进入博客列表页,在博客列表页可以选择查看全文,如果是自己写的博客也可以选择删除。
二、准备工作
创建一个maven项目,在pom.xml中引入Mysql依赖、Servlet依赖以及Jackson依赖。
<dependencies> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency> <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.13.5</version> </dependency> </dependencies>
创建目录结构,并将前端页面文件添加到目录中。
web.xml文件的内容如下:
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> </web-app>
三、设计实现数据库
创建blog_system数据库。
create database blog_system ;
创建blog表,有blogId(博客编号) 、title(博客标题)、content(博客内容)、userId(作者编号)、postTime(发布时间)这些属性。
create table blog ( blogId int primary key auto_increment, title varchar(1024), content mediumtext, userId int, postTime datetime );
向blog表中插入一些数据。
insert into blog values(null, '这是第一篇博客', '从今天开始, 我要认真学 Java', 1, now()); insert into blog values(null, '这是第二篇博客', '从昨天开始, 我要认真学 Java', 1, now()); insert into blog values(null, '这是第三篇博客', '从前天开始, 我要认真学 Java', 1, now()); insert into blog values(null, '这是第一篇博客', '从今天开始, 我要认真学 C++', 2, now()); insert into blog values(null, '这是第二篇博客', '从昨天开始, 我要认真学 C++', 2, now());
创建user表,有userId(用户编号)、userName(用户名)、password(密码)这些属性。
create table user( userId int primary key auto_increment, userName varchar(100) unique , password varchar (100) );
同样也向user表中插入一些数据。
insert into user values(null,'zhangyi','1234'); insert into user values(null,'zhanger','1234'); insert into user values(null,'zhangsan','1234');
四、封装数据库
创建User类和Blog类
public class Blog { private int blogId; private String title; private String content; private int userId; private Timestamp postTime; public Blog(int blogId, String title, String content, int userId, Timestamp postTime) { this.blogId = blogId; this.title = title; this.content = content; this.userId = userId; this.postTime = postTime; } 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 int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public String getPostTime() { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return simpleDateFormat.format(postTime); } public void setPostTime(Timestamp postTime) { this.postTime = postTime; } }
public class User { private int userId; private String userName; private String password; public User(int userId, String userName, String password) { this.userId = userId; this.userName = userName; this.password = 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; } }
使用JDBC连接数据库
创建DBUtil连接数据库以及相关资源的关闭。
public class DBUtil { private static final String url = "jdbc:mysql://127.0.0.1:3306/blog_system?characterEncoding=utf8&useSSL=false"; private static final String user = "root"; private static final String password = "1234"; private static volatile DataSource dataSource; private static DataSource getDataSource(){ if(dataSource == null){ synchronized (DBUtil.class){ if (dataSource == null){ dataSource = new MysqlDataSource(); ((MysqlDataSource)dataSource).setURL(url); ((MysqlDataSource)dataSource).setUser(user); ((MysqlDataSource)dataSource).setPassword(password); } } } return dataSource; } public static Connection getConnection() throws SQLException { return (Connection) getDataSource().getConnection(); } public static void closeResource(Connection connection, PreparedStatement statement, ResultSet resultSet) { if(connection != null){ try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } if(statement != null){ try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } } if(resultSet != null){ try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
创建BlogDAO类操作数据库中的Blog表
public class BlogDAO { //获取博客表中的所有博客信息 public List<Blog> getAllBlogs() { List<Blog> list = new LinkedList<>(); Connection connection = null; PreparedStatement statement = null; ResultSet resultSet = null; try { connection = DBUtil.getConnection(); String sql = "select * from blog order by postTime desc"; statement = connection.prepareStatement(sql); resultSet = statement.executeQuery(); while(resultSet.next()){ Blog blog = new Blog(); blog.setBlogId(resultSet.getInt("blogId")); String content = resultSet.getString("content"); if(content.length() > 50){ content = content.substring(0,50); } blog.setContent(content); blog.setTitle(resultSet.getString("title")); blog.setUserId(resultSet.getInt("userId")); blog.setPostTime(resultSet.getTimestamp("postTime")); list.add(blog); } } catch (SQLException e) { e.printStackTrace(); }finally { DBUtil.closeResource(connection,statement,resultSet); } return list; } //获取指定id的博客 public Blog getBlog(int blogId) { Connection connection = null; PreparedStatement statement = null; ResultSet resultSet = null; try { connection = DBUtil.getConnection(); String sql = "select * from blog where userId = ?"; statement = connection.prepareStatement(sql); statement.setInt(1,blogId); resultSet = statement.executeQuery(); Blog blog = new Blog(); if(resultSet.next()) { blog.setBlogId(resultSet.getInt("blogId")); blog.setContent(resultSet.getString("content")); blog.setTitle(resultSet.getString("title")); blog.setUserId(resultSet.getInt("userId")); blog.setPostTime(resultSet.getTimestamp("postTime")); return blog; } } catch (SQLException e) { e.printStackTrace(); } finally { DBUtil.closeResource(connection,statement,resultSet); } return null; } //插入一篇博客 public void addBlog(Blog blog) throws SQLException { Connection connection = null; PreparedStatement statement = null; try { connection = DBUtil.getConnection(); 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()); statement.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { DBUtil.closeResource(connection,statement,null); } } //删除一篇博客 public void deleteBlog(int blogId) throws SQLException { Connection connection = null; PreparedStatement statement = null; try { connection = DBUtil.getConnection(); String sql = "delete from blog where userId = ?"; statement = connection.prepareStatement(sql); statement.setInt(1,blogId); statement.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { DBUtil.closeResource(connection,statement,null); } } }
创建UserDAO类操作数据库中的user表
public class UserDAO { //通过用户名查询用户信息 public User getUserByName(String name){ Connection connection = null; PreparedStatement statement = null; ResultSet resultSet = null; try { connection = DBUtil.getConnection(); String sql = "select * from user where userName = ?"; statement = connection.prepareStatement(sql); statement.setString(1,name); 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.closeResource(connection,statement,resultSet); } return null; } //通过id查询用户信息 public User getUserById(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.closeResource(connection,statement,resultSet); } return null; } //删除用户 public void deleteUser(int userId) throws SQLException { Connection connection = null; PreparedStatement statement = null; try { connection = DBUtil.getConnection(); String sql = "delete from user where userId = ?"; statement = connection.prepareStatement(sql); statement.setInt(1,userId); statement.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { DBUtil.closeResource(connection,statement,null); } } }
五、实现具体功能
1、实现博客列表页
约定前后端交互接口
//请求 GET/blog //响应 { { blogId:xx; title:xxx; content:xxxx; userId:xx; postTime:xxx; }, { blogId:xx; title:xxx; content:xxxx; userId:xx; postTime:xxx; }, …… }
服务器端
重写doGet方法来获取数据库中的博客列表,设置响应格式为Json,字符集为utf8,先定义一个Json对象objectMapper,然后利用blogDAO对象从数据库中获取到所有的博客,并将其存到List中,然后利用Json对象将其转换成字符串,并写进响应中。
//获取数据库中的博客列表 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ObjectMapper objectMapper = new ObjectMapper(); //设置响应格式 resp.setContentType("application/json;charset=utf8"); BlogDAO blogDAO = new BlogDAO(); List<Blog> blogs = blogDAO.getAllBlogs(); //将blogs对象装成Json格式的字符串 String respJson = objectMapper.writeValueAsString(blogs); resp.getWriter().write(respJson); }
客户端
页面加载的时候利用ajax访问服务器,获取到数据库中的博客列表,因为博客列表的数目不确定,就需要构造div,对body进行遍历,向div中添加各种元素。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>blog-list</title> <link rel="stylesheet" href="common.css"> <link rel="stylesheet" href="container.css"> </head> <body> <div class="nav"> <img src="logo.jpg"> <span class="name">博客系统</span> <span class="blank"></span> <a href="#">主页</a> <a href="#">写博客</a> <a href="#">注销</a> </div> <div class="container"> <div class="left"> <div class="card"> <img class="avatar" src="x.jpg" > <h3>小郭同学</h3> <a class="gitee" href="#"> gitee地址</a> <div class="counter"> <span>文章</span> <span>专栏</span> </div> <div class="counter"> <span>6</span> <span>2</span> </div> </div> </div> <div class="right"> <!--<div class="blog"> <div class="title"><!–第一篇博客–></div> <div class="time"><!–2022-6-09–></div> <div class="desc"><!– Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusantium error esse impedit magni placeat possimus repellendus veniam, veritatis voluptas? Cum deserunt explicabo neque non placeat quaerat quam? At, blanditiis, non!–></div> <a class="a" href="#">查看全文</a> </div>--> </div> </div> <script src="https://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script> <script> //在页面加载的时候,利用ajax向服务器发送请求,获取到博客列表信息后,在页面进行显示 function getBlogList(){ $.ajax({ type:'get', url:'blog', success:function(body){ //获取到的body是JS对象的数组,因为数组大小每次可能都不一样,就需要构造div let rightDiv = document.querySelector('.right'); for(let blog of body){ let blogDiv = document.createElement('div'); blogDiv.className = 'blog'; let titleDiv = document.createElement('div'); titleDiv.className = 'title'; titleDiv.innerHTML = blog.title; blogDiv.appendChild(titleDiv); let postTimeDiv = document.createElement('div'); postTimeDiv.className = 'postTime'; postTimeDiv.innerHTML = blog.postTime; blogDiv.appendChild(postTimeDiv); let descDiv = document.createElement('div'); descDiv.className = 'desc'; descDiv.innerHTML = blog.content; blogDiv.appendChild(descDiv); let a = document.createElement('a'); a.innerHTML = '查看全文'; a.href = 'blog-detail.html?blogId='+blog.blogId; blogDiv.appendChild(a); rightDiv.appendChild(blogDiv); } }, error:function(){ alert('获取博客列表失败') } }) }; getBlogList(); </script> </body> </html>
2、实现博客详情页
约定前后端交互接口
//请求 GET/blog?blogId=1 //响应 HTTP/1.1 200 OK Content-Type:application/json { blogId:xx; title:xxx; content:xxxx; userId:xx; postTime:xxx; }
服务器端
可以在实现博客列表详情页列表的服务器端代码进行扩充,首先查看请求参数中是否有blogId,若有则表示是指定一篇博客,就利用BlogDAO对象获取到指定的博客,然后写到响应中。
@WebServlet("/blog") public class BlogServlet extends HttpServlet { //获取数据库中的博客列表 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ObjectMapper objectMapper = new ObjectMapper(); //设置响应格式 resp.setContentType("application/json;charset=utf8"); BlogDAO blogDAO = new BlogDAO(); String result = req.getParameter("blogId"); if(result == null){ List<Blog> blogs = blogDAO.getAllBlogs(); //将blogs对象装成Json格式的字符串 String respJson = objectMapper.writeValueAsString(blogs); resp.getWriter().write(respJson); }else{ Blog blog = blogDAO.getBlog(Integer.parseInt(result)); String respJson = objectMapper.writeValueAsString(blog); resp.getWriter().write(respJson); } } }
客户端
查看全文时就会跳转到博客详情页,利用ajax来处理响应,对于content由于在编辑博客时用的markdown字符串进行编辑的,但是展示时需要渲染后的结果,就需要利用引入editor依赖来完成。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Blog-detail</title> <link rel="stylesheet" href="common.css"> <link rel="stylesheet" href="container.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="logo.jpg"> <span class="name">博客系统</span> <span class="blank"></span> <a href="#">主页</a> <a href="#">写博客</a> <a href="#">注销</a> </div> <div class="container"> <div class="left"> <div class="card"> <img class="avatar" src="x.jpg" > <h3>小郭同学</h3> <a class="gitee" href="#"> gitee地址</a> <div class="counter"> <span>文章</span> <span>专栏</span> </div> <div class="counter"> <span>6</span> <span>2</span> </div> </div> </div> <div class="right"> <div class="blog"> <h3 class="title"></h3> <div class="postTime"></div> <div id="desc"> </div> <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script> <script> function getBlog(){ //在页面加载的时候,利用ajax向服务器发送请求,获取到博客列表信息后,在页面进行显示 $.ajax({ type:'get', //表示blog=blogId url:'blog'+location.search, success:function(body){ let h3 = document.querySelector(".blog>h3"); h3.innerHTML = body.title; let postTime = document.querySelector(".postTime"); postTime.innerHTML = body.postTime; //由于在编辑博客时用的markdown字符串进行编辑的,但是展示时需要渲染后的结果 // let content = document.querySelector('.desc'); // content.innerHTML = body.content; editormd.markdownToHTML('desc', { markdown: body.content }); }, error:function(){ alert("查看全文失败!"); } }); } getBlog(); </script> </body> </html>
实现博客系统2:https://developer.aliyun.com/article/1521722?spm=a2c6h.13148508.setting.30.55b44f0eMfupsy