简易项目:servlet实现个人博客(超级详细)

成品展示

  1. 博客登录页

简易项目:servlet实现个人博客(超级详细)_第1张图片

2.博客预览页

简易项目:servlet实现个人博客(超级详细)_第2张图片

  1. 博客详情页

简易项目:servlet实现个人博客(超级详细)_第3张图片

4.博客编写发布页

简易项目:servlet实现个人博客(超级详细)_第4张图片

5.可访问网址

http://43.143.248.172:8080/blog_system/login.html

用户名:zhangsan

密码:123

  1. 确认需求

1.1核心功能

1.1.1用户登陆和注销

这一部分需要满足用户的登入和注销操作,同时需要判断用户名和密码的正确性,我们使用JDBC从数据库中拉取数据来实现

1.1.2发布博客

这一部分我们需要引入markdown来进行博客系统的编写页面,并且通过JDBC将发布的博客写入到数据库中

1.1.3删除博客

这一部分我们需要将数据从数据库中将对应的博客进行删除,同时需要跳转到博客预览页

1.1.4浏览博客

这一部分我们通过JDBC将博客的标题和正文一部分展示到博客预览页

  1. 具体实现

2.1项目基础设计

2.1.1数据库概要设计

首先我们要先设计数据库,基于我们的系统比较简易,所以只有两张表

  1. 博客表(blog)

简易项目:servlet实现个人博客(超级详细)_第5张图片

  1. 用户表(user)

简易项目:servlet实现个人博客(超级详细)_第6张图片

然后我们根据这两张表,去创建数据库

--创建数据库并设置字符集为utf8mb4

create database if not exists blog_system charset utf8mb4;

use blog_system;



drop table if exists blog;

create table blog(
blogId int primary key auto_increment,
title varchar(256),
content varchar(1025),
postTime datetime,
userId int
);

create table user(
userId int primary key auto_increment,
username varchar(20),
password varchar(20)
);

由于我们没有实现注册功能,所以我们提前在用户表中插入两条数据

insert into user values(null, "zhangsan", "123");
insert into user values(null, "lisi", "123");

2.1.2引入JDBC依赖

这里我们可以去中央仓库去查找,我这里给出的是5.1.49版本的依赖


        
            mysql
            mysql-connector-java
            5.1.49
        

2.1.3封装数据库的DATaSource

由于数据库中的操作我们会经常使用到,所以我们将其封装成一个类DBUtill

使用JDBC编写结果如下(代码中有详细注释):

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;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 王久实
 * Date: 2022-12-23
 * Time: 21:01
 */
public class DBUtil {
//    通过单例模式创建数据源
    private static DataSource dataSource = null;

    private static DataSource getDataSource(){
//        这里的if主要是为了提高程序的运行速率,假如没有这个if,那么就会使后续的线程继续去等待锁,然后进去判断if,再出来,再进去一个,就增大了开销
        if(dataSource == null){
//            这里主要是为了加锁,防止多个线程进去创建实例
            synchronized (DBUtil.class){
//              这里就是防止多个线程进入了第一层if,等待锁释放后,再进来继续创建实例
                if(dataSource == null){
                    dataSource = new MysqlDataSource();
                    ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/blog_system_2?characterEncoding=utf8&useSSL=false");
//                    这里设置数据库的用户名,一般都填写root
                    ((MysqlDataSource)dataSource).setUser("root");
//                    这里填写数据库的密码,没有密码就和我这里一样填空
                    ((MysqlDataSource)dataSource).setPassword("");
                }
            }
        }
        return dataSource;
    }

//    建立连接
    public static Connection getConnection() throws SQLException {
//        这一段代码可以分解来看
//        DataSource dataSource = getDataSource();
//        dataSource.getConnection();
//        本质就是对上面创建的Datasource获取Connection连接
        return getDataSource().getConnection();
    }

//    关闭资源
//    注意:这里需要后创建的资源先关闭
    public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet){
//        这里不能直接throws,如果用throws,程序抛异常了,就会影响到后面的资源关闭
        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();
            }
        }
    }
}

2.1.4创建博客类

很明显,我们需要两个类,一个博客类(Blog)一个用户类(User),这里的类需要和数据库中的元素对应

import java.sql.Timestamp;
import java.text.SimpleDateFormat;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 王久实
 * Date: 2022-12-23
 * Time: 20:59
 */
public class Blog {
    private int blogId;
    private String title;
    private String content;
    private Timestamp postTime;
    private 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 String getPostTime() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy-MM-dd HH:mm:ss");
        return simpleDateFormat.format(postTime);
    }

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

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }
}

这里有一个小细节,就是我们获取时间的那里,不能直接使用post Time,因为从数据库中获取的postTime是一个时间戳,并不方便用户阅读,所以我们这里使用一个类(SimpleDateFormat)来构造用户能够阅读的时间类型,这里这个类首先实例化的时候,就在构造方法中声明了转换后的类型,后续只需要调用format()方法,即可将postTime转换为我们设置类型的字符串,从而提升用户的体验感

2.1.5创建用户类

User类没啥好说的,只需要和数据库元素对应即可

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 王久实
 * Date: 2022-12-23
 * Time: 20:33
 */
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;
    }


}

2.1.6针对Blog类进行增删改查

我们设置好实体类之后,就可以通过JDBC对数据库进行增删改查操作了,这里我们将Blog的增删改查进行封装成一个BlogDao类

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

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 王久实
 * Date: 2022-12-23
 * Time: 21:55
 * +-----------------------+
 * | Tables_in_blog_system |
 * +-----------------------+
 * | blog                  |
 * | user                  |
 * +-----------------------+
 */
public class BlogDao {
//    增加一篇博客
    public static void insertBlog(Blog blog){
        Connection connection = null;
        PreparedStatement statement = null;
//        sql语句的编写
        String sql = "insert into blog values(null,?,?,now(),?)";
        try {
//            调用DBUtil中的方法,建立连接
            connection = DBUtil.getConnection();
//            将编写好的sql语句进行处理
            statement = connection.prepareStatement(sql);
//            对语句中的?进行设置操作
            statement.setString(1,blog.getTitle());
            statement.setString(2,blog.getContent());
            statement.setInt(3,blog.getUserId());
//            执行sql语句
            statement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
//            调用DBUtil中的方法,对资源进行释放
            DBUtil.close(connection,statement,null);
        }
    }

//    根据博客Id查询对应的博客
    public static Blog selectBlogByBlogId(int blogId){
        Connection connection = null;
        PreparedStatement statement = null;
//        用来接收查询到的数据
        ResultSet resultSet = null;
        Blog blog = new Blog();
        String sql = "select * from blog where blogId = ?";
        try {
            connection = DBUtil.getConnection();
            statement = connection.prepareStatement(sql);
            statement.setInt(1,blogId);
            resultSet = statement.executeQuery();
//            if判断是否读到数据
            if(resultSet == null){
                return null;
            }
//            将读到的数据设置到实体类中去
            blog.setBlogId(blogId);
            blog.setUserId(resultSet.getInt("userId"));
            blog.setContent(resultSet.getString("content"));
            blog.setTitle(resultSet.getString("title"));
            blog.setPostTime(resultSet.getTimestamp("postTime"));
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtil.close(connection,statement,resultSet);
        }
        return blog;
    }

//    查看所有博客
    public static List selectAll(){
        List blogs = new ArrayList<>();
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        String sql = "select * from blog";
        try {
            connection = DBUtil.getConnection();
            statement = connection.prepareStatement(sql);
            resultSet = statement.executeQuery();
//            这里和迭代器的用法一样,使用next表示往下一个数据依次执行
            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() > 80){
                    content = content.substring(0,81) + "...";
                }
                blog.setContent(content);
                blog.setPostTime(resultSet.getTimestamp("postTime"));
                blog.setUserId(resultSet.getInt("userId"));
                blogs.add(blog);
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtil.close(connection,statement,resultSet);
        }
        return blogs;
    }
//删除博客

    public static void deleteBlog(Blog blog){
        Connection connection = null;
        PreparedStatement statement = null;
        String sql = "delete from blog where blogId = ?";
        try {
            connection = DBUtil.getConnection();
            statement = connection.prepareStatement(sql);
            statement.setInt(1,blog.getUserId());
            statement.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.close(connection,statement,null);
        }
    }
}

2.1.7对User类进行增删改查

这里和上面的方法基本如出一辙,就不过多赘述

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

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 王久实
 * Date: 2022-12-23
 * Time: 21:24
 */
public class UserDao {
    //    通过用户名查询
    public static User selectByName(String userName) {
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        try {
//            建立上连接
            connection = DBUtil.getConnection();
//            构造sql
            String sql = "select * from user where username = ?";
            statement = connection.prepareStatement(sql);
            statement.setString(1, userName);

//            执行sql
            resultSet = statement.executeQuery();

//          遍历写入
            User user = new User();
            user.setUserId(resultSet.getInt("userId"));
            user.setUserName(userName);
            user.setPassword(resultSet.getString("password"));
//            返回结果
            return user;
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBUtil.close(connection, statement, resultSet);
        }
        return null;
    }
//    通过用户Id来查询
    public static User selectById(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();
            User user = new User();
            user.setUserId(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;
    }
}



2.2实现博客预览页

2.2.1接口约定

这里和前端技术人员约定好前后端交互的接口,这里约定的接口如下:

简易项目:servlet实现个人博客(超级详细)_第7张图片

然后根据博客预览页,进行相关代码的编写

这里还有一个点,和前端约定的格式是json格式的,所以我们还需要导入json的依赖和servlet的依赖,通过中央仓库去复制即可

        

        
        
            javax.servlet
            javax.servlet-api
            3.1.0
            provided
        
        

        
        
            com.fasterxml.jackson.core
            jackson-databind
            2.13.4.1
        

2.2.2博客预览页后端代码

前端代码我会放到最后

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

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 王久实
 * Date: 2022-12-29
 * Time: 10:54
 */

@WebServlet("/blog")
public class BlogServlet extends HttpServlet {
    ObjectMapper objectMapper = new ObjectMapper();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("application/json;charset=utf8");
       
        
//        博客列表页
//        创建List集合来接收blog,用BlogDao中的方法去数据库中查询
            List blogs = BlogDao.selectAll();
//        将查询到的结果返回给前端
            resp.getWriter().write(objectMapper.writeValueAsString(blogs));
        
    }

    
}

2.3实现博客详情页

2.3.1接口约定

简易项目:servlet实现个人博客(超级详细)_第8张图片

这里的请求中加了query string来标识博客的Id

2.3.2博客详情页后端代码

由于这里也使用/blog的GET请求,所以我们就可以在原来的博客预览页代码中加上一个if语句,从而区分博客详情页和博客预览页,这里可以通过blogId是否为null来判断,因为博客列表页发送过来的数据中是不包含query string 的所以这里可以用这个进行一个区分

@WebServlet("/blog")
public class BlogServlet extends HttpServlet {
    ObjectMapper objectMapper = new ObjectMapper();
//  这里是和前端约定好的GET请求
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        由于前端约定的格式是json格式的
        resp.setContentType("application/json;charset=utf8");
//        从前端发来的请求中获取到blogId
        String blogId = req.getParameter("blogId");
//        这里进行判断是博客预览页还是博客详情页
        if(blogId == null){
//        博客列表页
            List blogs = BlogDao.selectAll();
            resp.getWriter().write(objectMapper.writeValueAsString(blogs));
        }else {
//            博客详情页
            Blog blog = BlogDao.selectBlogByBlogId(Integer.parseInt(blogId));
            resp.getWriter().write(objectMapper.writeValueAsString(blog));
        }
    }

}

2.4登陆逻辑

2.4.1接口约定

简易项目:servlet实现个人博客(超级详细)_第9张图片

2.4.2登陆逻辑后端代码

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;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 王久实
 * Date: 2022-11-30
 * Time: 20:50
 */
@WebServlet("/login")
public class BlogLoginServlet extends HttpServlet {


    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        设置接收到请求的类型
        req.setCharacterEncoding("utf-8");
//        设置返回的响应的类型
        resp.setContentType("text/http;charset=utf8");
//        从前端页面获取用户名和密码
        String username = req.getParameter("username");
        String password = req.getParameter("password");
//       判断获取到的用户名密码是否为空值
        if(username == null || password == null || username.equals("") || password.equals("")){
            resp.getWriter().write("用户名或密码为空");
            return;
        }
        User user = new User();
        UserDao userDao = new UserDao();
        user = userDao.selectByName(username);
//        将获取到的用户名密码和数据库中的用户名密码进行比对
        if(user == null || !user.getPassword().equals(password)){
//            这里的前端页面并没有进行设置,所以只是返回一个字符串响应
            resp.getWriter().write("用户名或密码错误");
            return;
        }
//        说明用户名密码验证成功了
//  建立一个会话
//        这里的true表示如果没有会话就创建一个会话,如果存在则返回已拥有的会话
        HttpSession session = req.getSession(true);
//        在上一句获取到的会话中保存user对象,当客户端带着这个session进行访问的时候,服务器会根据session返回对应的内容
        session.setAttribute("user",user);
//        重定向到博客预览页
            resp.sendRedirect("blog_list.html");
    }
}

2.4.3强制博客预览页和博客详情页登陆

我们这里限制一下,如果我们在通过网页直接访问博客预览页或者博客详情页的时候,我们需要检查登陆状态必须强制我们已经登陆了,才能 访问

接口的约定

简易项目:servlet实现个人博客(超级详细)_第10张图片

如果未登录,直接返回403进行拒绝访问

后端代码的实现

这里也用 /login,用GET请求,所以和上述代码可以放到同一个类中去

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;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 王久实
 * Date: 2022-11-30
 * Time: 20:50
 */
@WebServlet("/login")
public class BlogLoginServlet extends HttpServlet {
    @Override
//    对登陆状态进行判定
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        获取会话,如果没有会话,就返回null
        HttpSession session = req.getSession(false);
//        如果session为null,则说明客户端没有带着session进行访问,所以就应该拒绝登录,直接返回403响应
        if(session == null){
//        返回403响应,即拒绝登陆
            resp.setStatus(403);
            return;
        }
//       如果有session,判断是否包含user对象
        User user = (User) session.getAttribute("user");
//        如果不包含user对象,则返回403
        if(user == null){
            resp.setStatus(403);
            return;
        }
//        包含就返回200
        resp.setStatus(200);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        设置接收到请求的类型
        req.setCharacterEncoding("utf-8");
//        设置返回的响应的类型
        resp.setContentType("text/http;charset=utf8");
//        从前端页面获取用户名和密码
        String username = req.getParameter("username");
        String password = req.getParameter("password");
//        判断获取到的用户名密码是否为空值
        if(username == null || password == null || username.equals("") || password.equals("")){
            resp.getWriter().write("用户名或密码为空");
            return;
        }
        User user = new User();
        UserDao userDao = new UserDao();
        user = userDao.selectByName(username);
//        将获取到的用户名密码和数据库中的用户名密码进行比对
        if(user == null || !user.getPassword().equals(password)){
//            这里的前端页面并没有进行设置,所以只是返回一个字符串响应
            resp.getWriter().write("用户名或密码错误");
            return;
        }
//        说明用户名密码验证成功了
//  建立一个会话
//        这里的true表示如果没有会话就创建一个会话,如果存在则返回已拥有的会话
        HttpSession session = req.getSession(true);
//        在上一句获取到的会话中保存user对象,当客户端带着这个session进行访问的时候,服务器会根据session返回对应的内容
        session.setAttribute("user",user);
//        重定向到博客预览页
            resp.sendRedirect("blog_list.html");
    }
}

2.5显示用户信息

在我们进行访问博客系统内部页面的时候,首先要确保已经登陆,那么我们就需要检查一下登陆状态,并且把登陆信息展示到状态栏,这里我们访问不同的界面,需要设置不同的方法来实现

2.5.1接口设计

简易项目:servlet实现个人博客(超级详细)_第11张图片

这里接口设计和上面的基本大同小异

2.5.2 后端代码实现

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 javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 王久实
 * Date: 2022-12-01
 * Time: 10:24
 */
@WebServlet("/userInfo")
public class UserInfoServlet extends HttpServlet {
//    这个是用来转换json数据的,所有设置了json的方式返回的都需要用mapper进行转换
    private ObjectMapper mapper = new ObjectMapper();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        设置响应的类型
        resp.setContentType("application/json;charset=utf8");
//        从前端获取博客Id(通过query string传递的)
        String blogId = req.getParameter("blogId");
//        判断是博客详情页还是博客预览页
        if (blogId == null){
            getUserInfoFromSession(req,resp);
        }else {
//        这里注意,前端传过来的blogId是字符型的,但是数据库中是int类型的,所以这里需要转成int类型的

            getUserInfoFromDB(req,resp,Integer.parseInt(blogId));
        }
    }

//      博客详情页
    private void getUserInfoFromDB(HttpServletRequest req, HttpServletResponse resp,int blogId) throws IOException {
        resp.setContentType("application/json;charset=utf8");
        BlogDao blogDao = new BlogDao();
//        从数据库中查询blogId对应的博客
        Blog blog = blogDao.selectOne(blogId);
        if(blog == null){
            resp.setStatus(404);
            resp.getWriter().write(mapper.writeValueAsString("blogId不存在"));
            return;
        }

        UserDao userDao = new UserDao();
//        根据Blog对象中的userId属性去User表中查找该篇博客的发布者
        User user = userDao.selectById(blog.getUserId());
        if(user == null){
            resp.setStatus(404);
            resp.getWriter().write(mapper.writeValueAsString("用户已经不存在"));
            return;
        }
//        这里是查询到了,我们不因该将密码页发送给客户端,所以置为空
        user.setPassword("");
//        将查询到的User信息返回给前端
        resp.getWriter().write(mapper.writeValueAsString(user));
    }

//    博客预览页
    private void getUserInfoFromSession(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        resp.setContentType("application/json;charset=utf8");
//        获取会话,通过会话中的内容,查询当前登陆的用户
        HttpSession session = req.getSession(false);
        if(session == null){
            resp.setStatus(403);
            resp.getWriter().write(mapper.writeValueAsString("当前未登录"));
            return;
        }
//        存入session中的user对象
        User user = (User) session.getAttribute("user");
        if(user == null){
            resp.setStatus(403);
            resp.getWriter().write(mapper.writeValueAsString("当前未登录"));
            return;
        }
//        将密码置为空
        user.setPassword("");
//        返回用户信息
        resp.getWriter().write(mapper.writeValueAsString(user));
    }
}

2.6注销用户

2.6.1接口约定

简易项目:servlet实现个人博客(超级详细)_第12张图片

注销后,跳转到登陆页面

2.6.2后端代码实现

其实这个很简单,只需要将session中的值进行修改,即可得到未登录状态

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;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 王久实
 * Date: 2022-12-01
 * Time: 16:36
 */
@WebServlet("/logout")
public class BlogLoginOutServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        获取会话
        HttpSession session = req.getSession(false);
        if(session == null){
            resp.setStatus(403);
            resp.getWriter().write("当前未登录");
            return;
        }
//        将session中的user对象删除
        session.removeAttribute("user");
//        跳转到登陆界面
        resp.sendRedirect("login.html");
    }
}

2.7发布博客

2.7.1接口约定

简易项目:servlet实现个人博客(超级详细)_第13张图片

发布完成之后,需要重定向到博客预览页

2.7.2后端代码实现

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 javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 王久实
 * Date: 2022-11-29
 * Time: 16:50
 */
@WebServlet("/blog")
public class BlogServlet extends HttpServlet {
    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();
        String blogId = req.getParameter("blogId");
        if(blogId == null){
            List blogs = blogDao.selectAll();
            resp.getWriter().write(objectMapper.writeValueAsString(blogs));
        }else {
            Blog blog = blogDao.selectOne(Integer.parseInt(blogId));
            resp.getWriter().write(objectMapper.writeValueAsString(blog));
        }
    }

//  发布博客
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        获取会话
        HttpSession session = req.getSession(false);
        if(session == null){
            resp.setStatus(403);
            resp.setContentType("text/html;charset=utf8");
            resp.getWriter().write("当前未登录");
            return;
        }
//        检查user对象是否存在
        User user = (User) session.getAttribute("user");
        if(user == null){
            resp.setStatus(403);
            resp.setContentType("text/html;charset=utf8");
            resp.getWriter().write("当前未登录");
            return;
        }
//        设置字符集
        req.setCharacterEncoding("utf8");
//        从前端获取标题和正文
        String title = req.getParameter("title");
        String content = req.getParameter("content");
//        将新博客设置到blog实例
        Blog blog = new Blog();
        BlogDao blogDao = new BlogDao();
        blog.setTitle(title);
        blog.setContent(content);
        blog.setUserId(user.getUserId());
//        将新博客设置到数据库中去
        blogDao.insert(blog);
//        跳转到博客预览页
        resp.sendRedirect("blog_list.html");
        
    }
}

2.8删除博客

2.8.1接口约定

简易项目:servlet实现个人博客(超级详细)_第14张图片

删除失败就返回403,拒绝访问,成功就返回博客预览页

2.8.2后端代码实现

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;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 王久实
 * Date: 2022-12-01
 * Time: 17:44
 */
@WebServlet("/blog_delete")
public class BlogDeleteServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        获取会话
        HttpSession session = req.getSession(false);
        if(session == null){
            resp.setStatus(403);
            resp.setContentType("text/html;charset=utf8");
            resp.getWriter().write("当前没有登陆");
            return;
        }
        User user = (User) session.getAttribute("user");
        if(user == null ){
            resp.setStatus(403);
            resp.setContentType("text/html;charset=utf8");
            resp.getWriter().write("当前没有登陆");
            return;
        }
//        从前端的query string获取到blogId
        String blogId =req.getParameter("blogId");
//        判断是否存在blogId参数
        if(blogId == null){
            resp.setStatus(404);
            resp.setContentType("text/html;charset=utf8");
//            如果没有查找到该文章,就直接返回blogId有误
            resp.getWriter().write("blogId有误");
            return;
        }
        BlogDao blogDao = new BlogDao();
//        因为blogId
        Blog blog = blogDao.selectOne(Integer.parseInt(blogId));
//        查看这个博客是否存在,需要将前端传过来的字符串转换成int类型
        if(blog == null){
            resp.setStatus(403);
            resp.setContentType("text/html;charset=utf8");
            resp.getWriter().write("找不到该博客");
            return;
        }
//        查看有没有权限去删除这篇博客,即判断当前登陆的用户,是不是和当前的用户相符合
        if(user.getUserId() != blog.getUserId()){
            resp.setStatus(403);
            resp.setContentType("text/html;charset=utf8");
            resp.getWriter().write("当前没有权限删除该博客");
            return;
        }
//        从数据库中删除该博客
        blogDao.delete(Integer.parseInt(blogId));
        resp.setContentType("text/html;charset=utf8");
        resp.getWriter().write("删除博客成功");
//        跳转到博客预览页
        resp.sendRedirect("blog_list.html");

    }
}

3.将博客系统部署到云服务器

先准备一个云服务器,并且安装Linux系统

  1. 安装JDK

首先我们要先给我们的Linux上面安装一个JDK,可以执行

yum list | grep jdk
简易项目:servlet实现个人博客(超级详细)_第15张图片

可以看到,会出现很多版本的JDK,这里我们选择

这里我们使用命令

yum install java-1.8.0-openjdk-devel.i686
简易项目:servlet实现个人博客(超级详细)_第16张图片

这里就进行下载了然后输入y

即可下载成功

然后我们对我们安装是否成功进行测试,只需要输入以下命令行

javac

如果没显示找不到命令,而是给一大段文件,则说明安装成功了

  1. 安装Tomcat

这里和上面的操作基本如出一辙,继续使用操作yum list即可

yum list | grep tomcat

我们选择这个进行安装

或者我们将Windows上面下载好的往XShell里面一拖就可以了

这里我们安装好之后,进入tomcat的文件夹,然后进入bin文件夹

就可以看到这个

这个就是我们Tomcat的启动程序

但是我们要先给可执行权限,才可以执行程序

chmod +x *.sh

输入这段代码即可

这时候,看到的sh文件就是绿色的了

然后通过

sh startup.sh

就可以启动Tomcat了

这里我们验证一下,输入下面代码

ps aux | grep tomcat

可以得到如下

简易项目:servlet实现个人博客(超级详细)_第17张图片

这里划红线的是安装的Tomcat地址

或者我们使用

netstat -anp | grep 8080

这里我们就可以看到,8080端口正在使用,而我们的tomcat 正是运行在8080端口上的

  1. 安装MySQL

这里直接查看知乎一个大佬的文章,他的文章非常详细

CentOS 7 通过 yum 安装 MariaDB - 知乎 (zhihu.com)

这里我们进入数据库编辑则需要输入

mysql -uroot -p

然后输入密码,接着把博客系统的数据库部分,复制一份进去,别忘了,还需要将源代码中DBUtil中的数据库密码改一下,因为云服务器的数据库密码可能和你电脑自带的数据库密码不同

  1. 将博客系统打包,部署到云服务

4.1导入依赖

在博客系统中,我们需要导入一个依赖,从而使打包出来的文件变成war包

    war

    
        blog_system
        
            
                maven-war-plugin
                3.0.0
            
        
    
4.2打包
简易项目:servlet实现个人博客(超级详细)_第18张图片

使用这个对所需要的文件进行打包处理,然后将其拖到

tomcat的webapp目录下即可

到这里我们就完成了一个简易的博客系统,可以进行访问试一下

4.项目源码展示

这里为了方便大家取用,我直接把项目的gitee放在文章末尾

博客系统 · 王久实/JAVA - 码云 - 开源中国 (gitee.com)

前端代码在webapps里面,需要自取

你可能感兴趣的:(mysql,servlet,java,tomcat,linux)