JavaWeb 项目 --- 博客系统(前后分离)

文章目录

  • 效果展示
  • 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

效果展示

可以访问 http://124.223.113.147:8080/MyBlog1/home.html 进入我的项目

JavaWeb 项目 --- 博客系统(前后分离)_第1张图片
JavaWeb 项目 --- 博客系统(前后分离)_第2张图片
JavaWeb 项目 --- 博客系统(前后分离)_第3张图片

1. 创建 maven 项目

创建必要的目录.引入需要的依赖
JavaWeb 项目 --- 博客系统(前后分离)_第4张图片

在这里插入图片描述
在这里插入图片描述

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. 导入之前写好的前端代码

JavaWeb 项目 --- 博客系统(前后分离)_第5张图片

5. 实现博客主页界面

5.1 约定好前后端交互接口

JavaWeb 项目 --- 博客系统(前后分离)_第6张图片

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>Documenttitle>
    <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>2span>
                    <span>1span>
                div>
            div>
        div>
        <div class="right">
            
        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 约定好前后端交互接口

JavaWeb 项目 --- 博客系统(前后分离)_第7张图片

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>Documenttitle>
    <link rel="stylesheet" href="css/moreList.css">
    <link rel="stylesheet" href="css/common.css">
    
    <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>2span>
                    <span>1span>
                div>
            div>
        div>
        <div class="right"> 
            <div class="article">
                <h2 class="title">我的第一篇博客h2>
                <span class="date">2022-4-17span>
            
                <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 约定好前后端交互接口

JavaWeb 项目 --- 博客系统(前后分离)_第8张图片

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("");
            return;
        }

        UserDao userDao = new UserDao();
        User user = userDao.selectByName(username);
        if(user == null){
            resp.getWriter().write("");
            return;
        }
        if(!password.equals(user.getPassWord())){
            resp.getWriter().write("");
            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>Documenttitle>
    <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 约定好前后端交互接口

JavaWeb 项目 --- 博客系统(前后分离)_第9张图片

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("");
            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("");
                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 约定好前后端交互接口

JavaWeb 项目 --- 博客系统(前后分离)_第10张图片

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("");
            return;
        }

        session.removeAttribute("user");
        resp.sendRedirect("login.html");
    }
}

11. 实现发布博客功能

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

JavaWeb 项目 --- 博客系统(前后分离)_第11张图片

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("");
            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>Documenttitle>
    <link rel="stylesheet" href="css/common.css">
    <link rel="stylesheet" href="css/edit.css">
    
    <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 约定好前后端交互接口

JavaWeb 项目 --- 博客系统(前后分离)_第12张图片

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

JavaWeb 项目 --- 博客系统(前后分离)_第13张图片

#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里

JavaWeb 项目 --- 博客系统(前后分离)_第14张图片

12.4 更改 DetailsServlet中的代码

JavaWeb 项目 --- 博客系统(前后分离)_第15张图片

12.5 更改 art.html 中的代码

JavaWeb 项目 --- 博客系统(前后分离)_第16张图片

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("");
            return;
        }

        String blogId = req.getParameter("blogId");
        if(blogId == null || "".equals(blogId)){
            resp.getWriter().write("");
            return;
        }
        BlogDao blogDao = new BlogDao();
        blogDao.delete(Integer.parseInt(blogId));
        resp.sendRedirect("home.html");
    }
}

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

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

JavaWeb 项目 --- 博客系统(前后分离)_第17张图片

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

在上一步的delete中添加即可

JavaWeb 项目 --- 博客系统(前后分离)_第18张图片

13.3 更改 art.html 中的代码

JavaWeb 项目 --- 博客系统(前后分离)_第19张图片

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>Documenttitle>
    <link rel="stylesheet" href="css/common.css">
    <link rel="stylesheet" href="css/edit.css">
    
    <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("");
            return;
        }

        String blogId = req.getParameter("blogId");
        if(blogId == null || "".equals(blogId)){
            resp.setContentType("text/html;charset=utf-8");
            resp.getWriter().write("");
        }
        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("");
            return;
        }
        String title = req.getParameter("title");
        String content = req.getParameter("content");
        if(title == null || "".equals(title) || content == null || "".equals(content)){
            resp.getWriter().write("");
            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 约定好前后端交互的接口

JavaWeb 项目 --- 博客系统(前后分离)_第20张图片

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("");
            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 约定好前后端交互的接口

JavaWeb 项目 --- 博客系统(前后分离)_第21张图片

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更改即可
JavaWeb 项目 --- 博客系统(前后分离)_第22张图片

你可能感兴趣的:(Java,Web,数据库,mysql,maven)