博客系统后端(项目系列2)

这篇具有很好参考价值的文章主要介绍了博客系统后端(项目系列2)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

前言 :

1.准备工作

1.1创建项目

1.2引入依赖

1.3创建必要的目录

2.数据库设计

2.1博客数据

2.2用户数据

3.封装数据库

3.1封装数据库的连接操作

3.2创建两个表对应的实体类

3.3封装一些必要的增删改查操作

4.前后端交互逻辑的实现

4.1博客列表页

4.1.1约定前后端交互接口

4.1.2编写后端代码

4.1.3编写前端代码

4.1.4启动服务器测试

4.2博客详情页

4.2.1约定前后端交互接口

4.2.2编写后端代码

4.2.3编写前端代码

4.2.4启动服务器测试

4.3登录功能

4.3.1约定前后端交互接口

4.3.2前端代码编写

4.3.3后端代码编写

4.3.4启动服务器测试

4.4强制用户登录

4.4.1约定前后端接口

4.4.2编写后端代码

4.4.3编写前端代码

4.4.4启动服务器测试

4.5实现显示用户信息

4.5.1约定后端交互接口

4.5.2后端代码编写

4.5.3前端代码编写

4.5.4启动服务器测试

4.6针对于详情页进行设置

4.6.1约定前后端接口

4.6.2编写后端代码

4.6.3编写前端代码

4.6.4启动服务器测试

4.7用户退出登录

4.7.1约定前后端接口

4.7.2编写后端代码

4.7.3编写前端代码

4.7.4启动服务器测试

4.8实现发布博客

4.8.1约定前后端接口

4.8.2编写后端代码

4.8.3编写前端代码

4.8.4启动服务器测试 

结束语:


前言 :

在上一次的项目中小编主要是和大家分享了有关于博客系统前端代码的编写,接下来我们就来编写一下后端代码,以及前后端的交互。如果想要看前端的代码的编写请看这里☞http://t.csdn.cn/VZCqN

1.准备工作

1.1创建项目

博客系统后端(项目系列2),项目,servlet

1.2引入依赖

从maven中央仓库中给pom.xml中引入servlet、jackson和sql的依赖。

博客系统后端(项目系列2),项目,servlet

1.3创建必要的目录

博客系统后端(项目系列2),项目,servlet

2.数据库设计

在次之前我们需要明确我们需要在数据库中创建哪些表,以及每个表中都有哪些属性。

这里结合上次编写的博客的前端代码我们知道我们需要存储数据的需要有两个表,一个是博客数据,另一个是用户数据。下面我们就来分别看一下。

-- 一般对于建表的sql都会单独搞一个.sql文件来保存
-- 后续程序可能需要在不同的主机上部署,部署的时候就需要在对应的主机上把数据库也给建好
-- 把建表的sql保存好,方便在不同的机器上进行建库建表操作

2.1博客数据

在博客表中我们需要的属性有博客id、标题、正文、userId以及发布的时间。

接下来我们就来创建一下表。

.sql文件代码展示:

create database if not exists blog_system;
use blog_system;
drop table if exists blog;
create table blog(
    blogId int primary key auto_increment,
    title varchar(128),
    content varchar(4096),
    userId int,
    postTime datetime
);

sql语句展示:

博客系统后端(项目系列2),项目,servlet

结果展示:

博客系统后端(项目系列2),项目,servlet

2.2用户数据

在用户表中我们需要的属性有userId、username、password。

接下来我们就来创建一下表。

.sql文件代码展示:

drop table if exists user;
create table user (
    userId int primary key auto_increment,
    username varchar(50) unique,
    password varchar(50)
);

 sql语句展示:

博客系统后端(项目系列2),项目,servlet

结果展示:

博客系统后端(项目系列2),项目,servlet

3.封装数据库

这里我们是使用JDBC来进行封装操作的。

3.1封装数据库的连接操作

代码展示:

package model;

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 {
    //这个类中要提供DataSource,DataSource对于一个项目来说,有一个就可以了
    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("jdbc:mysql://127.0.0.1:3306/blog_system?characterEncoding=utf8&useSSL=false");
                    ((MysqlDataSource) dataSource).setUser("root");
                    ((MysqlDataSource) dataSource).setPassword("123456");
                }
            }
        }
        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创建两个表对应的实体类

需要在java代码中创建对应的类,表示这个两个实体。比如创建Blog类,Blog类的每一个对象就代表数据库的一个记录。

Blog代码展示:

package model;

import java.sql.Timestamp;

/**
 * 这个类表示数据库中blog表的内容
 * 每个Blog对象,就对应一个blog表中的一条记录
 */
public class Blog {
    private int blogId;
    private String title;
    private String content;
    private int userId;
    private Timestamp 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 Timestamp getPostTime() {
        return postTime;
    }

    public void setPostTime(Timestamp postTime) {
        this.postTime = postTime;
    }
}

User代码展示:
 

package model;

/**
 * 这个类表示数据库中的user表
 * ,每个User实例就代表user表中的一个记录
 */
public class User {
    private int userId;
    private String username;
    private 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.3封装一些必要的增删改查操作

BlogDao代码展示:

package model;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class BlogDao {
    //把一个Blog对象插入到数据库中
    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.setInt(3,blog.getUserId());
            //如果数据库表里面是datetime类型,插入数据的时候,按照TimeStamp来插入或者按照格式化时间来插入都是可以的
            statement.setTimestamp(4,blog.getPostTime());
            //3.执行SQL
            statement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.close(connection,statement,null);
        }
    }
    public List<Blog> selectAll() {
        List<Blog> blogs = new ArrayList<>();
        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"));
                blog.setTitle(resultSet.getString("title"));
                String content = resultSet.getString("content");
                if (content.length() > 100) {
                    content = content.substring(0,100) + "...";
                }
                blog.setContent(content);
                blog.setUserId(resultSet.getInt("userId"));
                blog.setPostTime(resultSet.getTimestamp("postTime"));
                blogs.add(blog);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.close(connection,statement,resultSet);
        }
        return blogs;
    }

    //指定一个博客的id来查询对应的博客
    public Blog selectOne(int blogId) {
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        try {
            connection = DBUtil.getConnection();
            String sql = "select * from blog where blogId = ?";
            statement = connection.prepareStatement(sql);
            statement.setInt(1,blogId);
            resultSet = statement.executeQuery();
            if (resultSet.next()) {
                Blog blog = new Blog();
                blog.setBlogId(resultSet.getInt("blogId"));
                blog.setTitle(resultSet.getString("title"));
                blog.setContent(resultSet.getString("content"));
                blog.setUserId(resultSet.getInt("userId"));
                blog.setPostTime(resultSet.getTimestamp("postTime"));
                return blog;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.close(connection,statement,resultSet);
        }
        return null;
    }

    //指定博客id来删除博客
    public void delete(int blogId) {
        Connection connection = null;
        PreparedStatement statement = null;
        try {
            connection = DBUtil.getConnection();
            String sql = "delete from blog where blogId = ?";
            statement = connection.prepareStatement(sql);
            statement.setInt(1,blogId);
            statement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.close(connection,statement,null);
        }
    }
}


UserDao代码展示:

package model;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class UserDao {
    //根据用户id来查找
    public User selectUserById(int userId) {
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        try {
            connection = DBUtil.getConnection();
            String sql = "select * from user where userId = ?";
            statement = connection.prepareStatement(sql);
            statement.setInt(1,userId);
            resultSet = statement.executeQuery();

            if (resultSet.next()) {
                User user = new User();
                user.setUserId(resultSet.getInt("userId"));
                user.setUsername(resultSet.getString("username"));
                user.setPassword(resultSet.getString("password"));
                return user;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.close(connection,statement,resultSet);
        }
        return null;
    }

    //根据用户姓名来查找
    public User selectUserByName(String username) {
        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,username);
            resultSet = statement.executeQuery();

            if (resultSet.next()) {
                User user = new User();
                user.setUserId(resultSet.getInt("userId"));
                user.setUsername(resultSet.getString("username"));
                user.setPassword(resultSet.getString("password"));
                return  user;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.close(connection,statement,resultSet);
        }
        return null;
    }
}

这里的Dao的意思就是Data Access Object,意思就是通过这样的对象来访问数据。 

4.前后端交互逻辑的实现

4.1博客列表页

4.1.1约定前后端交互接口

我们在传输数据之前要先来约定一下传输数据的格式是啥,那么下面我们就以以下的格式进行传输。

博客系统后端(项目系列2),项目,servlet

4.1.2编写后端代码

侧边创建的包。

博客系统后端(项目系列2),项目,servlet

代码展示:

package api;

import com.fasterxml.jackson.databind.ObjectMapper;
import model.Blog;
import model.BlogDao;

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("/blog")
public class BlogServlet extends HttpServlet {
    private ObjectMapper objectMapper = new ObjectMapper();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        BlogDao blogDao = new BlogDao();
        List<Blog> blogs = blogDao.selectAll();
        String respString = objectMapper.writeValueAsString(blogs);
        resp.setContentType("application/json;charset=utf8");
        resp.getWriter().write(respString);
    }
}

4.1.3编写前端代码

首先我们要将我们之前编写的前端的代码引入到该项目中。

博客系统后端(项目系列2),项目,servlet

博客系统后端(项目系列2),项目,servlet

代码展示:
 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>博客列表页</title>
    <link rel="stylesheet" href="css/common.css">
    <link rel="stylesheet" href="css/blog_list.css">
    <!-- 引入 jquery -->
    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
</head>
<body>
    <!-- 导航栏 -->
    <div class="nav">
        <!-- 图片的引入 -->
        <img src="image/nav.jpg">
        <!-- 标题 -->
        <div class="title">我的博客系统</div>
        <!-- 在这里我们使用一个简单粗暴的办法将后面的链接直接给挤过去 -->
        <div class="spacer"></div>

        <a href="blog_list.html">主页</a>
        <a href="blog_edit.html">写博客</a>
        <!-- 这里的地址后期讲解 -->
        <a href="">注销</a>
    </div>

    <!-- 版心的实现 -->
    <div class="container">
        <!-- 左侧信息 -->
        <div class="container-left">
            <!-- 这个div表示整个用户信息的区域 -->
            <div class="card">
                <!-- 用户的头像 -->
                <img src="image/userAvatar.jpg">

                <!-- 用户名 -->
                <h3>打工人</h3>

                <!-- GitHub地址 -->
                <a href="https://github.com/yaugaolele/Project.git">GitHub 地址</a>

                <!-- 统计信息 -->
                <div class="counter">
                    <span>文章</span>
                    <span>分类</span>
                </div>
                <div class="counter">
                    <span>2</span>
                    <span>1</span>
                </div>
            </div>
        </div>
        <!-- 右侧信息 -->
        <div class="container-right">
            <!-- <div class="blog">
                <div class="title">我的第一篇博客</div>
                <div class="date">2023-08-16 20:00:00</div>
                <div class="desc">
                    认真写博客,Lorem ipsum dolor sit amet consectetur adipisicing elit. Blanditiis, adipisci quia dignissimos non ut illo quo! Exercitationem molestias, eveniet necessitatibus debitis laboriosam magni quibusdam ex quam eaque, nam, voluptatum nisi!
                </div>
                <a href="blog_detail.html?html?blogId=1">查看全文 &gt;&gt; </a>
            </div> -->
        </div>
    </div>

    <script>
        //通过ajax给服务器发请求,获取到所有的博客数据,并且构造到页面上
        function getBlogs() {
            $.ajax({
                type:'get',
                url:'blog',
                success:function(body) {
                    //根据返回的数据,构造出页面中对应的元素
                    let containerRight = document.querySelector(".container-right");
                    for (const blog of body) {
                        let blogDiv = document.createElement("div");
                        blogDiv.className = 'blog';
                        let titleDiv = document.createElement("div");
                        titleDiv.className = 'title';
                        titleDiv.innerHTML = blog.title;
                        let dataDiv = document.createElement("div");
                        dataDiv.className = 'data';
                        dataDiv.innerHTML = blog.postTime;
                        let descDiv = document.createElement("div");
                        descDiv.className = 'desc';
                        descDiv.innerHTML = blog.content;
                        let a = document.createElement("a");
                        a.href = 'blog_detail.html?blogId=' + blog.blogId;
                        a.innerHTML = "查看全文 &gt;&gt;";

                        //把上述标签定义好之后,还需要进行组合
                        blogDiv.appendChild(titleDiv);
                        blogDiv.appendChild(dataDiv);
                        blogDiv.appendChild(descDiv);
                        blogDiv.appendChild(a);
                        containerRight.appendChild(blogDiv);
                    }
                }
            });
        }
        getBlogs();
    </script>
</body>
</html>

4.1.4启动服务器测试

在启动之前我们先来配置一下Smart Tomcat。

博客系统后端(项目系列2),项目,servlet

启动服务器观察页面的展示结果。

博客系统后端(项目系列2),项目,servlet可是发现现在的页面中没有显示任何数据,这是因为我们连接的是数据库,在数据库中没有数据的插入,所以现在我们来插入几条数据进入。

我们先在db.sql文档中编写好sql语句,然后再执行。

insert into blog values(null, '我的第一篇博客','这是博客正文',1,'2023-08-27 12:00:00');
insert into blog values(null, '我的第二篇博客','这是博客正文',2,'2023-08-28 12:00:00');

博客系统后端(项目系列2),项目,servlet

博客系统后端(项目系列2),项目,servlet

然后启动服务器,再次进行查看。

博客系统后端(项目系列2),项目,servlet

这里我们会发现有三个问题:

  • 问题一:时间显示不正确。
  • 问题二:按照习惯来说,新发布的博客应该是在最上面的。
  • 问题三:摘要部分应该显示的是一部分正文部分的内容,不是全部内容。

那么接下来我们就一一解决一下这两个问题。

①首先是时间的问题,这里显示的是时间戳,但是对于用户来说时间戳不便于阅读,所以我们应该显示成符合平时阅读习惯的写法,这里我们涉及到了后端和前端,那么到底是前端显示的问题呢?还是后端的问题呢?这里我们可以借助fiddler进行抓包来查看。

博客系统后端(项目系列2),项目,servlet

通过抓包我们可以发现我们在从后端拿到数据的时候就是一个时间戳,所以究其原因是后端的问题,那么我们就需要查看我们的代码,将给前端的数据要显示成一个格式的。

在下面这里后端返回的数据是jackson把blogs转换成json字符串直接返回的,jackson会遍历当前的blogs List,取到每个blog对象去调用getter方法,拿到对应的属性,构造成json字符串。

博客系统后端(项目系列2),项目,servlet

所以在Blog中对于getPostTime返回的数据类型应该是String类型的。

博客系统后端(项目系列2),项目,servlet

在返回的时候我们希望是格式化之后的一串字符串,那么该怎么进行格式化呢?这里SimpleDateFormat可以帮助我们有效的构造,但是里面的一些具体格式还需要我们自己进行设置。

博客系统后端(项目系列2),项目,servlet

博客系统后端(项目系列2),项目,servlet

这样当我再次启动服务器进行访问的时候时间就按照我们约定的正常显示了。

博客系统后端(项目系列2),项目,servlet

②另一个问题就是在显示的时候应该是最新发布博客在最上面,所以这里我们只需要修改查询语句即可。

博客系统后端(项目系列2),项目,servlet

这样就达到我们预期的效果了。

博客系统后端(项目系列2),项目,servlet

③摘要的截取问题。

按照下面的代码所示就可以对摘要进行截取了。

博客系统后端(项目系列2),项目,servlet

此时还需要设置一下前端CSS的样式,要不然可能文本就会超出范围。

博客系统后端(项目系列2),项目,servlet

这样就可以了。

博客系统后端(项目系列2),项目,servlet

4.2博客详情页

4.2.1约定前后端交互接口

博客系统后端(项目系列2),项目,servlet

注意:在这里的正文部分应该就是要完整的了。 

4.2.2编写后端代码

这里的后端代码只需要在我们之前编写的BlogServlet的基础上调整即可。

代码展示:

package api;

import com.fasterxml.jackson.databind.ObjectMapper;
import model.Blog;
import model.BlogDao;

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("/blog")
public class BlogServlet extends HttpServlet {
    private ObjectMapper objectMapper = new ObjectMapper();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //从query String 中查询一下看是否有blogId,如果有就认为是查询指定博客,如果没有就是查询所有博客
        BlogDao blogDao = new BlogDao();
        String blogId = req.getParameter("blogId");
        if (blogId == null) {
            List<Blog> blogs = blogDao.selectAll();
            String respString = objectMapper.writeValueAsString(blogs);
            resp.setContentType("application/json;charset=utf8");
            resp.getWriter().write(respString);
        }else {
            Blog blog = blogDao.selectOne(Integer.parseInt(blogId));
            String respString = objectMapper.writeValueAsString(blog);
            resp.setContentType("application/json;charset=utf8");
            resp.getWriter().write(respString);
        }
    }
}

此处的关键是根据blogId这个query string是否存在,来分两个情况讨论。 

4.2.3编写前端代码

代码展示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>博客详情页</title>
    <link rel="stylesheet" href="css/common.css">
    <link rel="stylesheet" href="css/blog_detail.css">
    <!-- 引入 jquery -->
    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <!-- 引入 editor.md 依赖 -->
    <link rel="stylesheet" href="editor.md/css/editormd.min.css" />
    <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/nav.jpg">
        <!-- 标题 -->
        <div class="title">我的博客系统</div>
        <!-- 在这里我们使用一个简单粗暴的办法将后面的链接直接给挤过去 -->
        <div class="spacer"></div>

        <a href="blog_list.html">主页</a>
        <a href="blog_edit.html">写博客</a>
        <!-- 这里的地址后期讲解 -->
        <a href="">注销</a>
    </div>

    <!-- 版心的实现 -->
    <div class="container">
        <!-- 左侧信息 -->
        <div class="container-left">
            <!-- 这个div表示整个用户信息的区域 -->
            <div class="card">
                <!-- 用户的头像 -->
                <img src="image/userAvatar.jpg">

                <!-- 用户名 -->
                <h3>打工人</h3>

                <!-- GitHub地址 -->
                <a href="https://github.com/yaugaolele/Project.git">GitHub 地址</a>

                <!-- 统计信息 -->
                <div class="counter">
                    <span>文章</span>
                    <span>分类</span>
                </div>
                <div class="counter">
                    <span>2</span>
                    <span>1</span>
                </div>
            </div>
        </div>
        <!-- 右侧信息 -->
        <div class="container-right">
            <!-- 博客标题 -->
            <h3></h3>
            <!-- 时间 -->
            <div class="date"></div>
            <div id="content">
            </div>
        </div>
    </div>
        <!-- <script src="js/app.js"></script> -->
        <script>
            function getBlog() {
                $.ajax({
                    type: 'get',
                    url: 'blog' + location.search,
                    success: function(body) {
                        // 设置博客的标题
                        let h3 = document.querySelector('.container-right h3');
                        h3.innerHTML = body.title;
                        // 设置发布时间
                        let dateDiv = document.querySelector('.container-right .date');
                        dateDiv.innerHTML = body.postTime;
                        // 设置正文. 正文内容应该是 markdown 格式的数据. 
                        // 此处要显示的应该是渲染过的 markdown 的内容, 而不是 markdown 的原始字符串. 
                        // 第一个参数, 是一个 html 元素的 id, 接下来渲染的结果会放到对应的 元素中. 
                        editormd.markdownToHTML('content', {markdown: body.content});
                    }
                });
            }
            getBlog();
        </script>
</body>
</html>

4.2.4启动服务器测试

这里我们使用的是Markdown编辑的方式,来插入的数据。

博客系统后端(项目系列2),项目,servlet

结果展示: 

博客系统后端(项目系列2),项目,servlet

4.3登录功能

4.3.1约定前后端交互接口

输入用户名和密码的时候我们需要触发登录操作。期望在点击的时候给后端发起一个http请求,后端做一些登录相关的逻辑。此处我们使用的是form来进行提交。博客系统后端(项目系列2),项目,servlet

博客系统后端(项目系列2),项目,servlet

注意:如果是通过302跳转前端必须使用form,不能使用ajax,ajax收到302的 响应是不会跳转的。

4.3.2前端代码编写

主要就是在之前登录前端页面的修改。主要修改的部分小编在下面已经画出来了。以及他与请求对应的关系。

博客系统后端(项目系列2),项目,servlet

4.3.3后端代码编写

代码展示:

package api;

import com.fasterxml.jackson.databind.ObjectMapper;
import model.User;
import model.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 {
    private ObjectMapper objectMapper = new ObjectMapper();
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.从请求中获取到用户名和密码
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        if (username == null || username.equals("") || password == null || password.equals("")) {
            //用户名和密码有残缺,登录失败
            String html = "<h3>登录失败,缺少用户名或者是密码!</h3>";
            resp.setContentType("text/html;charset=utf8");
            resp.getWriter().write(html);
            return;
        }
        //2.读取数据库,查看这里的用户名和密码是否和数据库中的匹配
        UserDao userDao = new UserDao();
        User user = userDao.selectUserByName(username);
        if (user == null){
            //用户名不存在
            String html = "<h3>用户名或者是密码错误!</h3>";
            resp.setContentType("text/html;charset=utf8");
            resp.getWriter().write(html);
            return;
        }
        if (!password.equals(user.getPassword())) {
            //密码错误
            String html = "<h3>用户名或者是密码错误!</h3>";
            resp.setContentType("text/html;charset=utf8");
            resp.getWriter().write(html);
            return;
        }
        //3.用户名呵密码都正确,登录成功,需要设置会话。
        //此处需要先创建出一个会话。
        HttpSession session = req.getSession(true);
        //此处就把用户对象存储到session中了,下次用户访问其他页面内的时候就可以直接拿到会话,进一步拿到之前的user对象了
        session.setAttribute("user", user);
        //4.返回一个重定向响应,能够跳转到博客列表页。
        resp.sendRedirect("blog_list.html");
    }
}

4.3.4启动服务器测试

①在数据库中准备两个user数据。 

博客系统后端(项目系列2),项目,servlet

②在登录页进行登录。

博客系统后端(项目系列2),项目,servlet

③登录之后就会跳转到博客列表页 并且会动态显示出登录人的信息。

博客系统后端(项目系列2),项目,servlet

4.4强制用户登录

我们这里作出以下设定,在用户访问博客列表页/详情页/编辑页的时候,必须是登录状态,如果未登录,则直接跳转到登录页要求用户进行登录。

这里我们在博客列表页/详情页/编辑页,页面加载的时候发起一个ajax请求,通过这个请求,访问服务器,获取到当前登录状态。

如果当前未登录,则跳转到登录页,如果已经登录则不做任何操作。

4.4.1约定前后端接口

博客系统后端(项目系列2),项目,servlet

4.4.2编写后端代码

我们在LoginServlet.java中编写一个doGet来判定当前登录状态。

package api;

import com.fasterxml.jackson.databind.ObjectMapper;
import model.User;
import model.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 {
    private ObjectMapper objectMapper = new ObjectMapper();
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.从请求中获取到用户名和密码
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        if (username == null || username.equals("") || password == null || password.equals("")) {
            //用户名和密码有残缺,登录失败
            String html = "<h3>登录失败,缺少用户名或者是密码!</h3>";
            resp.setContentType("text/html;charset=utf8");
            resp.getWriter().write(html);
            return;
        }
        //2.读取数据库,查看这里的用户名和密码是否和数据库中的匹配
        UserDao userDao = new UserDao();
        User user = userDao.selectUserByName(username);
        if (user == null){
            //用户名不存在
            String html = "<h3>用户名或者是密码错误!</h3>";
            resp.setContentType("text/html;charset=utf8");
            resp.getWriter().write(html);
            return;
        }
        if (!password.equals(user.getPassword())) {
            //密码错误
            String html = "<h3>用户名或者是密码错误!</h3>";
            resp.setContentType("text/html;charset=utf8");
            resp.getWriter().write(html);
            return;
        }
        //3.用户名呵密码都正确,登录成功,需要设置会话。
        //此处需要先创建出一个会话。
        HttpSession session = req.getSession(true);
        //此处就把用户对象存储到session中了,下次用户访问其他页面内的时候就可以直接拿到会话,进一步拿到之前的user对象了
        session.setAttribute("user", user);
        //4.返回一个重定向响应,能够跳转到博客列表页。
        resp.sendRedirect("blog_list.html");
    }

    //通过这个方法,判定用户的登录状态,以登录,返回200,未登录返回403
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //看当前请求是否存在会话,并且当前会话是否包含user对象。
        HttpSession session = req.getSession(false);
        if (session == null) {
            //会话不存在,未登录
            resp.setStatus(403);
            return;
        }
        User user = (User) session.getAttribute("user");
        if (user == null) {
            //虽然会话对象存在,但是用户对象没有,未登录
            resp.setStatus(403);
            return;
        }
    }
}

4.4.3编写前端代码

博客系统后端(项目系列2),项目,servlet

针对于上述判定用户登录状态的情况需要对于博客列表页、编辑页、详情页都需要弄一份,所以我们直接将它提取出来,然后在进行引入即可。

①提取

博客系统后端(项目系列2),项目,servlet②引入 

博客系统后端(项目系列2),项目,servlet

博客系统后端(项目系列2),项目,servlet博客系统后端(项目系列2),项目,servlet

4.4.4启动服务器测试

博客系统后端(项目系列2),项目,servlet

4.5实现显示用户信息

在博客列表页显示的是登录用户的信息,在博客详情页我们要显示的是文章作者的信息。所以这里我们就需要对着两个部分分别进行获取。

4.5.1约定后端交互接口

博客系统后端(项目系列2),项目,servlet

4.5.2后端代码编写

博客系统后端(项目系列2),项目,servlet

4.5.3前端代码编写

现在我们基于现有的代码进行调整,上述的三个页面都在使用getLoginStatus,实际上只是需要在博客列表页,做出调整,另外两个页面变,所以这里我们就直接在博客列表页对其进行复制一份刚才抽取出来的代码即可。

博客系统后端(项目系列2),项目,servlet

4.5.4启动服务器测试

博客系统后端(项目系列2),项目,servlet

4.6针对于详情页进行设置

这里我们针对详情页进行处理,详情页这里显示的是当前文章作者的信息,此时我们就需要先根据blogId查询到文章对象,然后进一步拿到文章作者的id,再根据id查询对应的作者名字,显示到页面上。

4.6.1约定前后端接口

博客系统后端(项目系列2),项目,servlet

4.6.2编写后端代码

这里我们创建一个新的Servlet来处理上述的请求。

代码展示:
 

package api;

import com.fasterxml.jackson.databind.ObjectMapper;
import model.Blog;
import model.BlogDao;
import model.User;
import model.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 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 {
        String blogId = req.getParameter("blogId");
        if (blogId == null || blogId.equals("")) {
            //直接返回一个userId为0的对象,因为最终返回的是一个json数据
            //此处也是返回json格式比较好,如果返回一个html,前端处理就会比较麻烦
            String respJson = objectMapper.writeValueAsString(new User());
            resp.setContentType("application/json;charset=utf8");
            resp.getWriter().write(respJson);
            System.out.println("参数给定的blogId为空!");
            return;
        }
        //2.查询数据库,查询对应的Blog对象
        BlogDao blogDao = new BlogDao();
        Blog blog = blogDao.selectOne(Integer.parseInt(blogId));
        if (blog == null) {
            String respJson = objectMapper.writeValueAsString(new User());
            resp.setContentType("application/json;charset=utf8");
            resp.getWriter().write(respJson);
            System.out.println("参数给定的blogId为空!");
            return;
        }
        //3.根据blog中的userId,查询作者信息
        UserDao userDao = new UserDao();
        User user = userDao.selectUserById(blog.getUserId());
        if (user == null) {
            String respJson = objectMapper.writeValueAsString(new User());
            resp.setContentType("application/json;charset=utf8");
            resp.getWriter().write(respJson);
            System.out.println("参数给定的blogId为空!");
            return;
        }
        //4.把user对象返回给页面
        String respJson = objectMapper.writeValueAsString(user);
        resp.setContentType("application/json;charset=utf8");
        resp.getWriter().write(respJson);
    }
}

4.6.3编写前端代码

代码展示:
 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>博客详情页</title>
    <link rel="stylesheet" href="css/common.css">
    <link rel="stylesheet" href="css/blog_detail.css">
    <!-- 引入 jquery -->
    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <!-- 引入 editor.md 依赖 -->
    <link rel="stylesheet" href="editor.md/css/editormd.min.css" />
    <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/nav.jpg">
        <!-- 标题 -->
        <div class="title">我的博客系统</div>
        <!-- 在这里我们使用一个简单粗暴的办法将后面的链接直接给挤过去 -->
        <div class="spacer"></div>

        <a href="blog_list.html">主页</a>
        <a href="blog_edit.html">写博客</a>
        <!-- 这里的地址后期讲解 -->
        <a href="">注销</a>
    </div>

    <!-- 版心的实现 -->
    <div class="container">
        <!-- 左侧信息 -->
        <div class="container-left">
            <!-- 这个div表示整个用户信息的区域 -->
            <div class="card">
                <!-- 用户的头像 -->
                <img src="image/userAvatar.jpg">

                <!-- 用户名 -->
                <h3></h3>

                <!-- GitHub地址 -->
                <a href="https://github.com/yaugaolele/Project.git">GitHub 地址</a>

                <!-- 统计信息 -->
                <div class="counter">
                    <span>文章</span>
                    <span>分类</span>
                </div>
                <div class="counter">
                    <span>2</span>
                    <span>1</span>
                </div>
            </div>
        </div>
        <!-- 右侧信息 -->
        <div class="container-right">
            <!-- 博客标题 -->
            <h3></h3>
            <!-- 时间 -->
            <div class="date"></div>
            <div id="content">
            </div>
        </div>
    </div>
        <script src="js/app.js"></script>
        <script>
            function getBlog() {
                $.ajax({
                    type: 'get',
                    url: 'blog' + location.search,
                    success: function(body) {
                        // 设置博客的标题
                        let h3 = document.querySelector('.container-right h3');
                        h3.innerHTML = body.title;
                        // 设置发布时间
                        let dateDiv = document.querySelector('.container-right .date');
                        dateDiv.innerHTML = body.postTime;
                        // 设置正文. 正文内容应该是 markdown 格式的数据. 
                        // 此处要显示的应该是渲染过的 markdown 的内容, 而不是 markdown 的原始字符串. 
                        // 第一个参数, 是一个 html 元素的 id, 接下来渲染的结果会放到对应的 元素中. 
                        editormd.markdownToHTML('content', {markdown: body.content});
                    }
                });
            }
            getBlog();

            function getAuthor() {
                $.ajax({
                    type:'get',
                    url:'user' + location.search,
                    success:function(body) {
                        //把响应中得到的user对象的数据给构造到页面上。
                        if(body.userId == 0) {
                            //服务器没有找到匹配的用户
                            alert("当前未找到匹配的作者信息!");
                            return;
                        }
                        //body是一个合法的user对象
                        let h3 = document.querySelector('.card h3');
                        h3.innerHTML = body.username;
                    }
                });
            }
            getAuthor();
        </script>
</body>
</html>

4.6.4启动服务器测试

 博客系统后端(项目系列2),项目,servlet

4.7用户退出登录

我们在写前端页面的时候有一个按钮是注销按钮,这里我们来实现一下注销操作,它是一个a标签,在我们点击的时候就会出发2一个get请求,服务器在收到这个get请求之后,就可以把当前用户的会话中的user对象给删除掉。

4.7.1约定前后端接口

博客系统后端(项目系列2),项目,servlet

4.7.2编写后端代码

代码展示:
 

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 {
        HttpSession session = req.getSession(false);
        if (session == null) {
            //用户本来就是没登录,谈不上注销,不过此处也没必要报错,直接跳转到登录页面即可。
            resp.sendRedirect("login.html");
            return;
        }
        //user 存在,就删除了,不存在也不会有副作用
        session.removeAttribute("user");
        resp.sendRedirect("login.html");
    }
}

4.7.3编写前端代码

这里我们只需要给导航栏中有注销按钮的a标签的href中加上跳转的地址即可。

博客系统后端(项目系列2),项目,servlet

4.7.4启动服务器测试

我们在博客列表页中点击注销按钮。

博客系统后端(项目系列2),项目,servlet

接下来就会直接跳转到登录页。

博客系统后端(项目系列2),项目,servlet

4.8实现发布博客

在博客编辑页中用户写的博客标题和正文就可以随便点击“发布”按钮而进行上传,服务器就可以保存上述数据到数据库中,接下来后续就可以在博客列表页中看到刚才新的博客了。

4.8.1约定前后端接口

这里我们依旧使用form表单的形式来进行提交。

博客系统后端(项目系列2),项目,servlet

4.8.2编写后端代码

这里我们是从请求中拿到标题和正文,从会话中拿到用户登录状态(作者id),获取到系统时间,然后构造出来一个Blog对象,最后将数据插入到数据库中。

代码展示:
 

package api;

import com.fasterxml.jackson.databind.ObjectMapper;
import model.Blog;
import model.BlogDao;
import model.User;

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;
import java.sql.Timestamp;
import java.util.List;

/**
 * 通过这个类来实现一些后端提供的接口
 */
@WebServlet("/blog")
public class BlogServlet extends HttpServlet {
    private ObjectMapper objectMapper = new ObjectMapper();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 从 query string 中查询一下看是否有 blogId. 如果有就认为是查询指定博客; 如果没有就是查询所有博客.
        BlogDao blogDao = new BlogDao();
        String blogId = req.getParameter("blogId");
        if (blogId == null) {
            List<Blog> blogs = blogDao.selectAll();
            String respString = objectMapper.writeValueAsString(blogs);
            resp.setContentType("application/json;charset=utf8");
            resp.getWriter().write(respString);
        } else {
            Blog blog = blogDao.selectOne(Integer.parseInt(blogId));
            String respString = objectMapper.writeValueAsString(blog);
            resp.setContentType("application/json;charset=utf8");
            resp.getWriter().write(respString);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf8");
        //1.先从请求中拿到标题和正文
        String title = req.getParameter("title");
        String content = req.getParameter("content");
        if (title == null || title.equals("") || content == null || content.equals("")){
            String html = "<h3>title或者content为空! 新增博客失败!</h3>";
            resp.setContentType("text/html;charset=utf8");
            resp.getWriter().write(html);
            return;
        }
        //2.从会话中拿到作者id
        HttpSession session = req.getSession(false);
        if (session == null) {
            String html = "<h3>当前用户还未登录!新增博客失败!</h3>";
            resp.setContentType("text/html;charset=utf8");
            resp.getWriter().write(html);
            return;
        }
        User user = (User) session.getAttribute("user");
        if (user == null) {
            String html = "<h3>当前用户还未登录!新增博客失败!</h3>";
            resp.setContentType("text/html;charset=utf8");
            resp.getWriter().write(html);
            return;
        }
        //3.构造Blog对象
        Blog blog = new Blog();
        blog.setUserId(user.getUserId());
        blog.setTitle(title);
        blog.setContent(content);
        blog.setPostTime(new Timestamp(System.currentTimeMillis()));

        //4.插入blog对象到数据库中
        BlogDao blogDao = new BlogDao();
        blogDao.insert(blog);
        //5.跳转到博客列表页
        resp.sendRedirect("blog_list.html");
    }
}

4.8.3编写前端代码

修改页面加上form表单,同时让页面提交的时候按照咱们的约定,构造出http请求。

博客系统后端(项目系列2),项目,servlet

在上述我们是采用Markdown编辑器,这个div内部的内容其实是被editor.md来做出个各种修改,那么这里就需要我们使用editor.md的官方文档中给出的方法来将我编辑框中 的内容提交给服务器了。步骤如下所示:

  1. 先给#editor div中方一个隐藏的textarea,后续编辑器输入框的内容就会被自动放到这个textarea中。
  2. 在editor.md的初始化代码中需要新增一个选项saveHTMLToTextarea:true。

博客系统后端(项目系列2),项目,servlet

博客系统后端(项目系列2),项目,servlet

上述中第④步和第⑤步是editor.md给我们提供的方案。 

代码展示:
 

<!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>博客编辑页</title>
    <link rel="stylesheet" href="css/common.css">
    <link rel="stylesheet" href="css/blog_edit.css">
    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <!-- 引入 editor.md 的依赖 -->
    <link rel="stylesheet" href="editor.md/css/editormd.min.css" />
    <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>
    <!-- 导航栏. nav 是 导航 这个词的缩写 -->
    <div class="nav">
        <!-- logo -->
        <img src="image/logo2.jpg" alt="">
        <div class="title">我的博客系统</div>
        <!-- 只是一个空白, 用来把后面的链接挤过去 -->
        <!-- 这是一个简单粗暴的写法~~ -->
        <div class="spacer"></div>
        <a href="blog_list.html">主页</a>
        <a href="blog_edit.html">写博客</a>
        <!-- 这里的地址回头再说 -->
        <a href="logout">注销</a>
    </div>

    <!-- 博客编辑页的版心 -->
    <div class="blog-edit-container">
        <form action="blog" method="post">
            <!-- 标题编辑区 -->
            <div class="title">
                <input type="text" id="title-input" name="title">
                <input type="submit" id="submit">
            </div>
            <!-- 博客编辑器 -->
            <!-- 把 md 编辑器放到这个 div 中 -->
            <div id="editor">
                <textarea name="content" style="display: none;"></textarea>
            </div>
        </form>
    </div>

    <script src="js/app.js"></script>
    <script>
        var editor = editormd("editor", {
            // 这里的尺寸必须在这里设置. 设置样式会被 editormd 自动覆盖掉. 
            width: "100%",
            // 设定编辑器高度
            height: "calc(100% - 50px)",
            // 编辑器中的初始内容
            markdown: "# 在这里写下一篇博客",
            // 指定 editor.md 依赖的插件路径
            path: "editor.md/lib/",
            saveHTMLToTextarea: true
        });

        getLoginStatus();
    </script>
</body>
</html>

4.8.4启动服务器测试 

博客系统后端(项目系列2),项目,servlet

博客系统后端(项目系列2),项目,servlet 博客系统后端(项目系列2),项目,servlet

结束语:

好了这节小编就给大分享到这里啦,希望这节对大家有关于项目的创建有一定帮助,想要学习的同学记得关注小编和小编一起学习吧!如果文章中有任何错误也欢迎各位大佬及时为小编指点迷津(在此小编先谢过各位大佬啦!)博客系统的整体项目我上传至我的码云Gitee中了,有需要的同学可以点击这里哦☞https://gitee.com/YAUGAOLELE/project

博客系统后端(项目系列2),项目,servlet文章来源地址https://www.toymoban.com/news/detail-685077.html

到了这里,关于博客系统后端(项目系列2)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 博客项目(前后端分离)(servlet实战演练)

    作者简介:大家好,我是未央; 博客首页: 未央.303 系列专栏:实战项目 每日一句:人的一生,可以有所作为的时机只有一次,那就是现在!!!! 文章目录 前言 项目介绍 一、MVC模式简介 1.1  MVC 模式含义 1.2 MVC 的工作流程 二、项目概述 2.1 项目的几个页面 2.2 功能大概

    2024年02月07日
    浏览(40)
  • 博客系统 Java Web 开发(Servlet)

    目录 一、准备工作 二、设计数据库 三、编写数据库代码 1、建表sql 2、封装数据库的连接操作 3、创建实体类 4、封装数据库的一些增删改查 (1)BlogDao 新增博客:  根据博客 id 来查询指定博客(用于博客详情页) 直接查询出数据库中所有的博客列表 删除博客 (2)UserDao

    2024年02月10日
    浏览(44)
  • 【基于前后端分离的博客系统】Servlet版本

      🎉🎉🎉 点进来你就是我的人了 博主主页: 🙈🙈🙈 戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔 🤺🤺🤺 目录 一. 项目简介  1. 项目背景 2. 项目用到的技术 3. 项目功能简单介绍  二. 博客系统页面设计  三. 项目准备工作 前后端交互约定内容的分析  1. 接口

    2024年02月08日
    浏览(40)
  • Servlet-搭建个人博客系统(MVC架构模式简介,maven的配置和使用)

    目录 1. MVC架构模式简介 2. maven的配置和使用 3. 项目总述🐻 3.1 🍎Controller层 3.2 🍎Model层 3.3 🍎View层 4. 页面的主要功能实现🐻 4.1 🍎登陆页面(login.html) 4.2 🍎博客列表页面(blog_index.html) 4.3 🍎博客详情页面(blog_detail.html) 4.4 🍎博客编辑页(blog_editor.html) 5.Conto

    2024年02月05日
    浏览(41)
  • 博客系统的后端设计(八) - 实现发布博客功能

    在原来的编辑页面点击发布文章按钮,是不会有什么效果的。 这是因为此时还不能实现前后端的交互。 请求使用 POST ,路径是 /blog title=这是标题content=这是正文 请求中要有 body,按照 form 表单的方式添加进去。 响应使用 HTTP/1.1 302 跳转到列表页:Location: blog.list.html 在一篇博

    2024年02月07日
    浏览(45)
  • 【JavaEE初阶】博客系统后端

    创建blog_system项目.将之前写的博客系统前端代码复制到webapp目录下. 在 pom.xml 中引入 Servlet mysql jackson 三个依赖: pom.xml : 结合之前的需求,在当前博客系统中,主要涉及到两个实体.即 用户 和 博客 . 经过分析我们可以得到, 用户 和 博客 之间是一对多的关系.即一个用户可以拥有多

    2024年02月14日
    浏览(40)
  • 个人博客系统(SSM版 前端+后端)

             在学习Servlet的时候,也写了一个博客系统,主要的就是使用servelet加Tomcat进行实现的,而这个项目 仅仅适合去学习Web项目开发的思想,并不满足当下企业使用框架的思想,进行学习过Spring,Spring Boot,Spring MVC以及MyBatis之后,我们就可以对之前的项目使用SSM框架的形式进行升

    2024年02月16日
    浏览(41)
  • 个人博客-SpringBoot+Vue3项目实战(3)Springboot+Mybatis创建后端项目

    🧨🧨🧨 大家好,我是搞前端的半夏 🧑,一个热爱写文的前端工程师 💻. 如果喜欢我的文章,可以关注 ➕ 点赞 👍 一起学习交流前端,成为更优秀的工程师~ 更多故事—点我探索新世界! 🧨🧨🧨 本专栏以搭建一个个人博客为目标,从前后端开发的开发,云服务的配置

    2023年04月10日
    浏览(50)
  • 博客系统后端设计(五) - 实现登录页面功能

    这里约定 请求 是一个 POST 请求,路径是 /login ,使用的是以下的格式: usernam=zhangsanpassword=123 响应是 HTTP/1.1 302 ,因为在成功登录之后,会直接跳转到列表页, 因此此时的 Location 是 blog.list.html 。 此时的响应要求是 302,因此要使用 form 表单才可以进行页面的跳转; 如果是

    2024年02月05日
    浏览(44)
  • 川西旅游网系统-前后端分离(前台vue 后台element UI,后端servlet)

    前台:tour_forword: 川西旅游网前端----前台 (gitee.com) 后台:tour_back: 川西旅游网-------后台 (gitee.com) 后端 :tour: 川西旅游网------后端 (gitee.com)

    2024年02月07日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包