[项目实战] 博客系统实现

news2024/9/22 7:24:09

水到渠成,冲呀冲呀

文章目录

  • 1 准备工作
    • 1.1 在Idea创建一个Maven项目
    • 1.2 引入servlet,masql,jackson依赖
    • 1.3 准备web.xml文件
  • 2. 数据库建表
  • 3. 封装DBUtil
  • 4. 创建实体类
    • 4.1 Blog类
    • 4.2 User类
  • 5. 封装数据库的增删改查
    • 5.1 对于blog的操作
      • 5.1.1 增加操作
      • 5.1.2 根据blogId查询
      • 5.1 3 根据userId进行查询
    • 5.2 对user表的操作
  • 6. 前后端接口的实现
    • 6.1 登陆页面
      • 6.1.1 对登录注册进行响应
      • 6.1.2 获取用户信息
    • 6.2 博客列表页,博客详情页,博客编辑页
      • 6.2.1 博客列表页与博客详情页
      • 6.2.2 博客编辑页
    • 6.3 注销用户信息
  • 7. 部署到服务器上



1 准备工作

1.1 在Idea创建一个Maven项目

File->new Project ->Maven.
在这里插入图片描述

1.2 引入servlet,masql,jackson依赖

在浏览器搜索maven仓库,下图为官网。
在这里插入图片描述
搜索sevlet->选择Java Servlet API->根据Tomcat版本,选择对应的Sevlet版本(在这个网站搜索对应版本 :http://tomcat.apache.org/whichversion.html ),我选的是3.0.1,点击。
在这里插入图片描述
复制如下代码
在这里插入图片描述
打开Maven中的pom.xml文件,复制到文件中,如下图所示,注意,要先添加 ,之后再复制
在这里插入图片描述
之后,再maven仓库中搜索mysql->选择mysql Connector Java->选择是5.几的版本,复制代码到pom.xml
在这里插入图片描述

在这里插入图片描述
再引入jackson依赖,在maven仓库中搜索jackson->选择jackson databind->这里选择的是2.14.2,复制代码到pom.xml中,如下图所示。
在这里插入图片描述

1.3 准备web.xml文件

在Idea中main目录下,创建目录,名字为webapp
在这里插入图片描述
在webapp目录下创建目录,目录名为WEB-INF
在WEB-INF目录下创建文件web.xml
在这里插入图片描述

直接复制如下代码到web.xml中,不需要记下来,用的时候复制就行。

<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
    <display-name>Archetype Created Web Application</display-name>
</web-app>

2. 数据库建表

这个项目中有两个对象,博客信息与用户信息,且用户与博客是一对多的关系。所以,我们需要在数据库中创建两张表,如下,图,在test目录下,创建文件- - dp.sql,我们在这里,写数据库创建表的操作,这里可以相当于代码的保存,下次创建数据库,直接在这里复制就行,不需要再重复敲一遍。
在这里插入图片描述
创建表,如下图所示。

在这里插入图片描述

3. 封装DBUtil

这里主要是IDEA与数据库的连接和断开操作。
首先,我们在java目录下新建两个包,一个名为api,用于编写前后端接口,另一个名为model,用于创建实体类,与表的增删改查。
在model包中,新建java文件,名为DBUtil
在这里插入图片描述
先建立一个用于数据库与IDEA建立和断开连接的对象。

 private static DataSource dataSource = new MysqlDataSource();
 

给对象添加属性,3306为数据库端口号,安装的时候,默认为3306,若有修改,则按修改之后的来。blog_system是要操作的数据库名,以自己的库名为基准,utf8为字符集设置。root为用户名,默认为root,之后,是数据库密码,填写自己的数据库密码即可。

	 static {
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/blog_system?characterEncoding=utf8&userSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("");
    }

之后,建立和断开连接

//建立连接
 	 public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
    
    //断开连接
    public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet){
        if(connection != null){
            try {
                connection.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(statement != null){
            try {
                statement.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(resultSet != null){
            try {
                resultSet.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
     }

总体代码如下

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 {
    private static DataSource dataSource = new MysqlDataSource();
    static {
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/blog_system?characterEncoding=utf8&userSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("");
    }
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
    public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet){
        if(connection != null){
            try {
                connection.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(statement != null){
            try {
                statement.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(resultSet != null){
            try {
                resultSet.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
}

4. 创建实体类

创建与表对应的blog类与user类,类中的一个对象就对相应数据库中的一条数据。
对象的属性与数据库中相对应。
如下图,在model包中新增Blog类与User类

4.1 Blog类

对应数据库里的属性,为Blog对象添加属性。
之后如下图,选中代码->右键->选中generate->选择Getter and Setter,一键添加get与set方法。
在这里插入图片描述
在方法getpostTime()中,由于要显示的时间是标准格式,所有,在这个方法中,要改一下代码。修改后如下图,注意,要改变方法的返回值类型。

	public String getPostTime() {
        //将时间格式化显示
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        return simpleDateFormat.format(postTime);
    }

4.2 User类

同样的操作,为User类添加成员属性与set、get方法。这步无特殊操作
在这里插入图片描述

5. 封装数据库的增删改查

我们首先要了解通过IDEA操作数据库的基本流程

  1. 建立连接
  2. 构造sql语句
  3. 执行sql语句
  4. 断开连接

5.1 对于blog的操作

5.1.1 增加操作

建立连接

connection = DBUtil.getConnection();

构造sql语句

			String sql = "insert into blog(null, ?, ?, ?, ?)";
			statement = connection.prepareStatement(sql);
			//这里给statement设置的属性,是根据传入的变量的类型和数目决定
            statement.setString(1, blog.getTitle());
            statement.setString(2, blog.getContext());
            statement.setString(3, blog.getPostTime());
            statement.setInt(4, blog.getUserId());

执行sql语句,这句语句要根据具体情况进行调节,如果是查询,就是statement.executeQuery();

statement.executeUpdate();

断开连接,这里的三个参数是coonection,statement,和resultSet,由于这里没有结果集,resultSet为空。

DBUtil.close(connection, statement, null);

完整代码如下

	public void add(Blog blog){
        Connection connection = null;
        PreparedStatement statement = null;
        try {
            connection = DBUtil.getConnection();
            String sql = "insert into blog(null, ?, ?, ?, ?)";
            statement = connection.prepareStatement(sql);
            statement.setString(1, blog.getTitle());
            statement.setString(2, blog.getContext());
            statement.setString(3, blog.getPostTime());
            statement.setInt(4, blog.getUserId());
            //执行sql语句
            statement.executeUpdate();

        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            DBUtil.close(connection, statement, null);
        }
    }

5.1.2 根据blogId查询

建立连接

connection = DBUtil.getConnection();

构造sql语句,由于这里传的参数是blogId,所以statement的属性是一个int.

String sql = "select * from blog where blogId = ?";
statement = connection.prepareStatement(sql);
statement.setInt(1, blogId);

执行sql语句,返回值为一个结果集。由于blogId唯一,所以结果集就有一条数据,遍历时用if就够了。创建一个新的Blog对象,将结果集的值赋给对应的对象成员变量,返回对象。

		resultSet = statement.executeQuery();
		if(resultSet.next()){
                Blog blog = new Blog();
                blog.setBlogId(resultSet.getInt("blogId"));
                blog.setTitle(resultSet.getString("blogTitle"));
                blog.setContext(resultSet.getString("context"));
                blog.setUserId(resultSet.getInt("userId"));
                return blog;
            }

断开连接

DBUtil.close(connection, statement, resultSet);

完整代码如下图所示

    public Blog selectById(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);
           //执行sql
           resultSet = statement.executeQuery();
           if(resultSet.next()){
               Blog blog = new Blog();
               blog.setBlogId(resultSet.getInt("blogId"));
               blog.setTitle(resultSet.getString("blogTitle"));
               blog.setContext(resultSet.getString("context"));
               blog.setUserId(resultSet.getInt("userId"));
               return blog;
           }
       } catch (SQLException throwables) {
           throwables.printStackTrace();
       }finally {
           DBUtil.close(connection, statement, resultSet);
       }
       return null;
   }

5.1 3 根据userId进行查询

输入用户名,打开用户的博客列表。 由于用户对于博客是一对多的关系,所以返回值是一个List集合
由于只是展示博客列表,不需要将博客的所有内容都展示出来。所以这里,我们要限制context的长度
完整代码如下

    public List<Blog> selectByUserId(int userId){
       List<Blog> blogs = new ArrayList<>();
       Connection connection = null;
       PreparedStatement statement = null;
       ResultSet resultSet = null;
       try {
           connection = DBUtil.getConnection();
           //构造sql语句
           String sql = "select * from blog where userId = ?";
           statement = connection.prepareStatement(sql);
           statement.setInt(1, userId);
           //执行sql
           resultSet = statement.executeQuery();
           while(resultSet.next()){
               Blog blog = new Blog();
               blog.setBlogId(resultSet.getInt("blogId"));
               blog.setTitle(resultSet.getString("title"));
               String context = resultSet.getString("context");
               if(context == null){
                   context = "";
               }
               if(context.length() > 100){

               }
               blog.setContext(resultSet.getString("context"));
               blog.setPostTime(resultSet.getTimestamp("postTime"));
               blog.setUserId(resultSet.getInt("useId"));
               blogs.add(blog);
           }
       } catch (SQLException throwables) {
           throwables.printStackTrace();
       }finally {
           DBUtil.close(connection, statement, resultSet);
       }
       return blogs;
   }

5.2 对user表的操作

操作有,增加用户信息,根据userId查询博客,根据username查询博客,完整代码如下,步骤是相同的,不做赘述

package model;

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

public class UserDao {
   public void add(User user){
       Connection connection = null;
       PreparedStatement statement = null;
       try {
           //和数据库建立连接
           connection = DBUtil.getConnection();
           //构造SQL 语句
           String sql = "insert into user (null, ?, ?)";
           statement = connection.prepareStatement(sql);
           statement.setString(1, user.getUsername());
           statement.setString(2, user.getPassword());
           //执行sql
           statement.executeUpdate();

       } catch (SQLException throwables) {
           throwables.printStackTrace();
       }finally {
           DBUtil.close(connection,statement,null);
       }
   }
   public User selectById(int userId){
       Connection connection = null;
       PreparedStatement statement = null;
       ResultSet resultSet = null;
       try {
           //建立连接
           connection = DBUtil.getConnection();
           //构造sql语句
           String sql = "select * from user where userI d =?";
           statement = connection.prepareStatement(sql);
           statement.setInt(1, userId);
           //执行sql
           resultSet = statement.executeQuery();
           if(resultSet.next()){
               User user = new User();
               user.setUserId(resultSet.getInt("userId"));
               user.setPassword(resultSet.getString("password"));
               return user;
           }
       } catch (SQLException throwables) {
           throwables.printStackTrace();
       }finally {
           DBUtil.close(connection,statement,resultSet);
       }
       return null;
   }

   public User selectByUsername(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();
           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 throwables) {
           throwables.printStackTrace();
       }finally {
           DBUtil.close(connection, statement, resultSet);
       }
       return null;
   }
}

6. 前后端接口的实现

6.1 登陆页面

提交用户名密码,若正确。则获取个人的博客列表。若用户未登录,则会强制跳转到登陆页面
所以,这里的post()方法就是对客户端提交登录的个人信息进行响应,并且根据信息的状态来判断是否能登陆成功
get()方法是返回用户信息。

6.1.1 对登录注册进行响应

设置请求的格式,以便Servlet去理解
设置响应的格式,使Servlet以固定的格式构造响应

req.setCharacterEncoding("utf8");
resp.setContentType("text/html;charset=utf8");

获取到用户名和密码

String username = req.getParameter("username");
String password = req.getParameter("password");

若有一个是空,则提示错误并返回

		if (username == null || "".equals(username) || password == null || "".equals(password)) {
            // 登录失败!!
            String html = "<h3>登录失败! 缺少 username 或者 password 字段</h3>";
            resp.getWriter().write(html);
            return;
        }

若都不为空,判断用户是否注册,也就是在服务器数据库中是否能查到用户名,若未注册,则自动注册,之后返回。

// 2. 读数据库, 看看用户名是否存在, 并且密码是否匹配
        UserDao userDao = new UserDao();
        User user = userDao.selectByUsername(username);
        if (user == null) {
// // 用户不存在.
//           自动创建用户信息,插入数据
      // 构造 User 对象
            User user2 = new User();
            user2.setUsername(username);
            user2.setPassword(password);
       // 插入数据库
            userDao.add(user2);
       //创造Session对话,将用户数据以键值对的形式保存到服务器数据库中
            HttpSession session = req.getSession(true);
            session.setAttribute("user", user2);
            resp.sendRedirect("blog_list.html");
            return;
        }

若用户存在,但密码不匹配,则显示错误信息,并返回。

	else if (!password.equals(user.getPassword())) {
            // 密码不对
            String html = "<h3>登录失败! 用户名或密码错误</h3>";
            resp.getWriter().write(html);
            return;
        }
       

若密码匹配,则创建对话,跳转到主页

 // 3. 用户名密码验证通过, 登录成功, 接下来就创建会话. 使用该会话保存用户信息.
       HttpSession session = req.getSession(true);
       session.setAttribute("user", user);
       // 4. 进行重定向. 跳转到博客列表页
       resp.sendRedirect("blog_list.html");
   }

完整代码如下

		protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置请求的编码. 告诉 servlet 按照啥格式来理解请求
        req.setCharacterEncoding("utf8");
        // 设置响应的编码. 告诉 servlet 按照啥格式来构造响应
        // resp.setCharacterEncoding("utf8");
        resp.setContentType("text/html;charset=utf8");
        // 1. 读取参数中的用户名和密码
        //    注意!! 如果用户名密码包含中文, 此处的读取可能会乱码.
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        if (username == null || "".equals(username) || password == null || "".equals(password)) {
            // 登录失败!!
            String html = "<h3>登录失败! 缺少 username 或者 password 字段</h3>";
            resp.getWriter().write(html);
            return;
        }
        // 2. 读数据库, 看看用户名是否存在, 并且密码是否匹配
        UserDao userDao = new UserDao();
        User user = userDao.selectByUsername(username);
        if (user == null) {
//            // 用户不存在.
//           自动创建用户信息,插入数据库。
            // 构造 User 对象
            User user2 = new User();
            user2.setUsername(username);
            user2.setPassword(password);
            // 插入数据库
            userDao.add(user2);
            HttpSession session = req.getSession(true);
            session.setAttribute("user", user2);
            resp.sendRedirect("blog_list.html");
            return;
        }else if (!password.equals(user.getPassword())) {
            // 密码不对
            String html = "<h3>登录失败! 用户名或密码错误</h3>";
            resp.getWriter().write(html);
            return;
        }
        // 3. 用户名密码验证通过, 登录成功, 接下来就创建会话. 使用该会话保存用户信息.
        HttpSession session = req.getSession(true);
        session.setAttribute("user", user);
        // 4. 进行重定向. 跳转到博客列表页
        resp.sendRedirect("blog_list.html");
    }

6.1.2 获取用户信息

使用get()方法,判断用户的登录状态。首先,用户登录一定是建立了Session对话,所以,首先判断session对象是否为空,为空,则需要重新登陆。

		HttpSession session = req.getSession(false);
        if (session == null) {
            // 未登录, 返回一个空的 user 对象
            User user = new User();
            String respJson = objectMapper.writeValueAsString(user);
            resp.getWriter().write(respJson);
            return;
        }

若session不为空,判断服务器数据库中user是否为空,有时特殊的网址或者App,例如中国农业银行这种,登录后长时间不使用,就会自动退出登录。这时session对话还在,但需要强制重新登录

		User user = (User) session.getAttribute("user");
        if (user == null) {
            user = new User();
            String respJson = objectMapper.writeValueAsString(user);
            resp.getWriter().write(respJson);
            return;
        }

一切都正常,则取出user对象,直接返回即可。

// 确实成功取出了 user 对象, 就直接返回即可.
        String respJson = objectMapper.writeValueAsString(user);
        resp.getWriter().write(respJson);

完整代码如下

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 {
        // 设置请求的编码. 告诉 servlet 按照啥格式来理解请求
        req.setCharacterEncoding("utf8");
        // 设置响应的编码. 告诉 servlet 按照啥格式来构造响应
        // resp.setCharacterEncoding("utf8");
        resp.setContentType("text/html;charset=utf8");
        // 1. 读取参数中的用户名和密码
        //    注意!! 如果用户名密码包含中文, 此处的读取可能会乱码.
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        if (username == null || "".equals(username) || password == null || "".equals(password)) {
            // 登录失败!!
            String html = "<h3>登录失败! 缺少 username 或者 password 字段</h3>";
            resp.getWriter().write(html);
            return;
        }
        // 2. 读数据库, 看看用户名是否存在, 并且密码是否匹配
        UserDao userDao = new UserDao();
        User user = userDao.selectByUsername(username);
        if (user == null) {
//            // 用户不存在.
//           自动创建用户信息,插入数据库。
            // 构造 User 对象
            User user2 = new User();
            user2.setUsername(username);
            user2.setPassword(password);
            // 插入数据库
            userDao.add(user2);
            HttpSession session = req.getSession(true);
            session.setAttribute("user", user2);
            resp.sendRedirect("blog_list.html");
            return;
        }else if (!password.equals(user.getPassword())) {
            // 密码不对
            String html = "<h3>登录失败! 用户名或密码错误</h3>";
            resp.getWriter().write(html);
            return;
        }
        // 3. 用户名密码验证通过, 登录成功, 接下来就创建会话. 使用该会话保存用户信息.
        HttpSession session = req.getSession(true);
        session.setAttribute("user", user);
        // 4. 进行重定向. 跳转到博客列表页
        resp.sendRedirect("blog_list.html");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("application/json; charset=utf8");
        // 使用这个方法来获取到用户的登录状态.

        // 如果用户未登录, 这里的会话就拿不到!!
        HttpSession session = req.getSession(false);
        if (session == null) {
            // 未登录, 返回一个空的 user 对象
            User user = new User();
            String respJson = objectMapper.writeValueAsString(user);
            resp.getWriter().write(respJson);
            return;
        }
        User user = (User) session.getAttribute("user");
        if (user == null) {
            user = new User();
            String respJson = objectMapper.writeValueAsString(user);
            resp.getWriter().write(respJson);
            return;
        }
        // 确实成功取出了 user 对象, 就直接返回即可.
        String respJson = objectMapper.writeValueAsString(user);
        resp.getWriter().write(respJson);
    }
}

6.2 博客列表页,博客详情页,博客编辑页

6.2.1 博客列表页与博客详情页

根据queryatring中是否能获取到blogId,来判断获取的是博客详情还是博客列表。

 		String blogId = req.getParameter("blogId");
        if (blogId == null) {
            //根据querystring是否为空,来判断,获取的是博客列表还是博客详情
            // queryString 不存在, 说明这次请求是获取博客列表
            List<Blog> blogs = blogDao.selectAll();
            // 需要把 blogs 转成符合要求的 json 格式字符串.
            String respJson = objectMapper.writeValueAsString(blogs);
            resp.setContentType("application/json; charset=utf8");
            resp.getWriter().write(respJson);
        }

不为空,则展示固定博客内容

			else{
            // queryString 存在, 说明本次请求获取的是指定 id 的博客.
            Blog blog = blogDao.selectById(Integer.parseInt(blogId));
            //blogId未查询到对应博客
            if (blog == null) {
                System.out.println("当前 blogId = " + blogId + " 对应的博客不存在!");
            }
            String respJson = objectMapper.writeValueAsString(blog);
            resp.setContentType("application/json; charset=utf8");
            resp.getWriter().write(respJson);
        }

6.2.2 博客编辑页

根据前端接口约定,post请求为博客编辑页的客户端请求
首先,根据session对话是否存在,及是否能获取到user,判断登陆是否有效

		HttpSession httpSession = req.getSession(false);
        if (httpSession == null) {
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write("当前未登录, 无法发布博客!");
            return;
        }
        User user = (User) httpSession.getAttribute("user");
        if (user == null) {
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write("当前未登录, 无法发布博客!");
            return;
        }

判断博客内容是否有误,获取body中的博客内容,并判断内容是否为空。

		req.setCharacterEncoding("utf8");
        String title = req.getParameter("title");
        String content = req.getParameter("content");
        if (title == null || "".equals(title) || content == null || "".equals(content)) {
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write("当前提交数据有误! 标题或者正文为空!");
            return;
        }

若一切正常,构造新的博客对象,插入数据库

		// 构造 Blog 对象
        Blog blog = new Blog();
        blog.setTitle(title);
        blog.setContent(content);
        blog.setUserId(user.getUserId());
        // 发布时间, 在 java 中生成 / 数据库中生成 都行
        blog.setPostTime(new Timestamp(System.currentTimeMillis()));
        // 插入数据库
        BlogDao blogDao = new BlogDao();
        blogDao.add(blog);

        // 跳转到博客列表页
        resp.sendRedirect("blog_list.html");

完整代码如下

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 {
        // 尝试获取一下 queryString 中的 blogId 字段.
        BlogDao blogDao = new BlogDao();
        String blogId = req.getParameter("blogId");
        //String userId = req.getParameter("userId");
        //String username = req.getParameter("username");
        if (blogId == null) {
            //根据querystring是否为空,来判断,获取的是博客列表还是博客详情
            // queryString 不存在, 说明这次请求是获取博客列表
            List<Blog> blogs = blogDao.selectAll();
            // 需要把 blogs 转成符合要求的 json 格式字符串.
            String respJson = objectMapper.writeValueAsString(blogs);
            resp.setContentType("application/json; charset=utf8");
            resp.getWriter().write(respJson);
        }else{
            // queryString 存在, 说明本次请求获取的是指定 id 的博客.
            Blog blog = blogDao.selectById(Integer.parseInt(blogId));
            //blogId未查询到对应博客
            if (blog == null) {
                System.out.println("当前 blogId = " + blogId + " 对应的博客不存在!");
            }
            String respJson = objectMapper.writeValueAsString(blog);
            resp.setContentType("application/json; charset=utf8");
            resp.getWriter().write(respJson);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 发布博客
        // 读取请求, 构造 Blog 对象, 插入数据库中即可!!
        HttpSession httpSession = req.getSession(false);
        if (httpSession == null) {
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write("当前未登录, 无法发布博客!");
            return;
        }
        User user = (User) httpSession.getAttribute("user");
        if (user == null) {
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write("当前未登录, 无法发布博客!");
            return;
        }
        // 确保登录之后, 就可以把作者给拿到了.

        // 获取博客标题和正文
        req.setCharacterEncoding("utf8");
        String title = req.getParameter("title");
        String content = req.getParameter("content");
        if (title == null || "".equals(title) || content == null || "".equals(content)) {
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write("当前提交数据有误! 标题或者正文为空!");
            return;
        }

        // 构造 Blog 对象
        Blog blog = new Blog();
        blog.setTitle(title);
        blog.setContent(content);
        blog.setUserId(user.getUserId());
        // 发布时间, 在 java 中生成 / 数据库中生成 都行
        blog.setPostTime(new Timestamp(System.currentTimeMillis()));
        // 插入数据库
        BlogDao blogDao = new BlogDao();
        blogDao.add(blog);

        // 跳转到博客列表页
        resp.sendRedirect("blog_list.html");
    }
}

6.3 注销用户信息

先判断用户是否注册,再移除用户信息。

	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession httpSession = req.getSession(false);
        if (httpSession == null) {
            // 未登录状态, 就直接提示出错.
            resp.setContentType("text/html; charset=utf8");
            resp.getWriter().write("当前未登录!");
            return;
        }
        //移除
        httpSession.removeAttribute("user");
        resp.sendRedirect("login.html");
    }

7. 部署到服务器上

打印war包,将war包拷贝到Tomcat的webapps目录下,即为部署完毕。执行结果如下。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/494416.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Notepad++配置C语言环境和C++环境

背景&#xff1a; Notepad是我们经常使用的编辑器&#xff0c;我们可以用它编译和运行各种类型的文档&#xff0c;其中就包括了C和C文档。但是编译和运行C或者C文档首先要配置编译环境&#xff0c;下面给大家分享一下如何在NotePad配置C/C编译环境。 工具&#xff1a; NoteP…

在全志V851S开发板上进行屏幕触摸适配

1.修改屏幕驱动 从ft6236 &#xff08;删掉&#xff0c;不要保留&#xff09;&#xff0c;改为下面的 路径&#xff1a;/home/wells/tina-v853-open/tina-v853-open/device/config/chips/v851s/configs/lizard/board.dts&#xff08;注意路径&#xff0c;要设置为自己的实际路…

docker-compose部署flume

一、docker-compose部署 1. 依赖的服务/组件 java8flume 1.9.0 2. 下载离线安装包 jdk8https://repo.huaweicloud.com/java/jdk/8u202-b08/jdk-8u202-linux-x64.tar.gzflume 1.9.0https://mirrors.tuna.tsinghua.edu.cn/apache/flume/1.9.0/apache-flume-1.9.0-bin.tar.gzs…

【Python入门篇】——Python基础语法(标识符与运算符)

作者简介&#xff1a; 辭七七&#xff0c;目前大一&#xff0c;正在学习C/C&#xff0c;Java&#xff0c;Python等 作者主页&#xff1a; 七七的个人主页 文章收录专栏&#xff1a; Python入门&#xff0c;本专栏主要内容为Python的基础语法&#xff0c;Python中的选择循环语句…

鸿蒙Hi3861学习六-Huawei LiteOS(软件定时器)

一、简介 软件定时器&#xff0c;是基于系统Tick时钟中断且由软件来模拟的定时器。当经过设定的Tick时钟计数值后&#xff0c;会触发用户定义的回调函数。定时精度与系统Tick时钟周期有关。 硬件定时器受硬件的限制&#xff0c;数量上不足以满足用户的实际需求。因此&#xff0…

【算法】什么是离散化

作者&#xff1a;指针不指南吗 专栏&#xff1a;算法篇 &#x1f43e;人类做题的过程&#xff0c;就是个暴搜的过程&#x1f43e; 文章目录 1.引入2.思路3.模板题 1.引入 特指有序、整数的离散化。 离散化&#xff0c;本质上是一种哈希&#xff0c;它在保持原序列大小关系的前…

肝一肝设计模式【六】-- 装饰器模式

系列文章目录 肝一肝设计模式【一】-- 单例模式 传送门 肝一肝设计模式【二】-- 工厂模式 传送门 肝一肝设计模式【三】-- 原型模式 传送门 肝一肝设计模式【四】-- 建造者模式 传送门 肝一肝设计模式【五】-- 适配器模式 传送门 文章目录 系列文章目录前言一、什么是装饰器模…

PLSQL Developer远程连接Oracle报错提示:“ORA-12541:TNS:无监听程序”的解决方案及思路

环境&#xff1a; 1、Windows Server 2、远程Oracle数据库&#xff1a;Oracle11g R2 3、PL/SQL程序&#xff1a;PL/SQL Developer Version 11.0.5.1790 (64 bit) 一、思路拆解&#xff1a; 此现象一般定位到远端的监听服务来找问题&#xff0c;在远端查看监听服务状态&#x…

DolphinScheduler 3.1.4详细教程

文章目录 第一章 DolphinScheduler介绍1.1 关于DolphinScheduler1.2 特性1.3 名词解释1.3.1 名词解释1.3.2 模块介绍 第二章 DolphinScheduler系统架构2.1 系统架构图2.2 架构说明该服务包含&#xff1a; 2.3 启动流程活动图2.4 架构设计思想2.4.1 去中心化vs中心化2.4.1.1 中心…

制作帮助中心过程中常见的误区与解决方法?

制作帮助中心是为了帮助用户了解产品和解决问题的重要手段。然而&#xff0c;在制作的过程中&#xff0c;我们可能会遇到一些误区&#xff0c;这些误区可能会导致我们的帮助中心无法达到预期的效果。因此&#xff0c;在本文中&#xff0c;我们将探讨制作帮助中心过程中常见的误…

今年产品经理这么卷,大家怎么面试的呢?

随着互联网行业的快速发展&#xff0c;产品经理这个职位变得越来越重要。产品经理需要具备多方面的能力&#xff0c;如市场调研、用户需求分析、产品设计、项目管理等等。因此&#xff0c;对于企业来说&#xff0c;招聘一名合适的产品经理是非常关键的。 而对于求职者来说&…

中国奇人周兴和——记四川星河建材有限公司董事长周兴和(中)

经商送礼 关押收审 从10多岁就开始闯荡社会的周兴和&#xff0c;可以说是社会大熔炉锻炼出来的奇人。他仅有小学文化程度&#xff0c;但是他的社会经验和社会知识却相当丰富&#xff0c;可以称得上是一个“社会学专家”。他口才超常&#xff0c;其处事能力、应变能力和综合能力…

ASEMI代理ADUM1250ARZ-RL7原装ADI车规级ADUM1250ARZ-RL7

编辑&#xff1a;ll ASEMI代理ADUM1250ARZ-RL7原装ADI车规级ADUM1250ARZ-RL7 型号&#xff1a;ADUM1250ARZ-RL7 品牌&#xff1a;ADI/亚德诺 封装&#xff1a;SOIC-8-150mil 批号&#xff1a;2023 引脚数量&#xff1a;8 工作温度&#xff1a;-40C~105C 安装类型&#…

4.7亿加元!爱立信和加拿大政府巨额投资量子计算

​ &#xff08;图片来源&#xff1a;网络&#xff09; 爱立信与加拿大政府的研发合作为期五年&#xff0c;项目价值超过4.7亿加元&#xff08;约合23.9亿元人民币&#xff09;&#xff0c;主要投入在爱立信位于安大略省渥太华和魁北克省蒙特利尔的工厂。预计将创造数百个工作…

三十岁成功入职京东啦!

我是小九小九不爱喝酒&#xff1a; 自己工作5年后&#xff0c;我成功拿到了京东的offer。下面说下我是如何从传统行业到京东的经历&#xff0c;希望能对你有所帮助。 本科我学的是机械电子工程专业&#xff0c;2013年本科毕业后&#xff0c;同学们大多到各研究所从事智能机器人…

真题详解(归纳法)-软件设计(六十七)

真题详解(关系模型)-软件设计&#xff08;六十六)https://blog.csdn.net/ke1ying/article/details/130495791 1、2018上半年 将小阶向大阶对奇&#xff0c;尾数右移动 解析&#xff1a; 0.23 * 10的2次方 0.22 *10的3次方 第一步&#xff1a;0.023*10的3次方&#xff0c;…

2022年收入增长23%,23年Q1大涨85%,上市后英方软件交出了一份亮眼的答卷

‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 2023年4月26日&#xff0c;英方软件&#xff08;688435&#xff09;公布了上市后首个业绩报告&#xff0c;包括2022年度财报和2023年第一季度财报。披露财报显示&#xff0c;英方软件在2022年实现营业收入1.97亿元&#xff…

ZC706P试验PL_DDR3内存条的步骤方法

ZC706P 板卡完全兼容XILINX官方的ZC706,当然也支持PL外挂的1G的DDR3内存条&#xff0c;这个片BLOG我提供从官方下载的一个文档和一个项目&#xff0c;演示一下验证DDR3的步骤。 步骤1&#xff1a;准备好板子&#xff0c;安装好软件。 链接&#xff1a;https://pan.baidu.com/s…

《创造》人生旅程

上个月读完的这本《创造》&#xff0c;发现作者是iPod的创造者&#xff0c;让我回想起我刚工作时买的iPod。iPod确是惊艳之作&#xff0c;那时我一个月挣1000元&#xff0c;竟毫不犹豫花了2000就买了&#xff0c;并一直伴随我直到进入智能手机时代。《创造》会写什么&#xff1…

日志项目之——将kafka数据存入hbase中

目录 1.添加依赖 2.在hbase shell界面中分别输入下面的语句&#xff0c;创建namespace和表 3.UserFriendToHB 4.UsersToHB 5.TrainToHB 6.EventsToHB 7.EventAttendeToHb 1.添加依赖 <dependencies><dependency><groupId>junit</groupId><a…