基于Servlet实现博客系统

目录

一、功能和效果

1、实现的功能

2、页面效果

二、功能具体实现

1、数据库

(1)设计数据库

(2)创建数据库表

(3)实现对blogs表和users表的操作并封装

2、登陆功能实现

(1)客户端发送请求

(2)服务器接收请求并做出响应

(3)效果

3、显示博客列表页

(1)客户端发送请求

(2)服务器接收请求并做出响应

(3)客户端收到响应后显示在页面上

(4)效果

4、显示博客详情页

(1)客户端发送请求

(2)服务器接收请求并做出响应

(3)客户端收到响应后显示在页面上

(4)效果

5、显示列表页用户信息

(1)客户端发送请求

(2)服务器接收请求并做出响应

(3)客户端收到响应后显示在页面

(4)效果

6、显示详情页用户信息

(1)客户端发送请求

(2)服务器接收请求并做出响应

(3)客户端收到响应后显示在页面

(4)效果

7、发布博客

(1)客户端发送请求

(2)服务器接收请求并做出响应

(3)效果

8、强制要求登陆

(1)客户端发送请求

(2)服务器接收请求并做出响应

​编辑

(3)效果

9、退出登陆

(1)客户端发送请求

(2)服务器处理请求 并做出响应

(3)效果


一、功能和效果

1、实现的功能

登陆功能、显示博客列表页、显示博客详情页、显示列表页用户信息、显示详情页用户信息、强制要求登陆、发布博客、退出登陆。

2、页面效果

(1)登陆

(2)博客列表页

(3)博客详情页

(4)列表页用户信息

(5)详情页用户信息

(5)发布博客

以上markdown编辑器需要引入第三方库editor.md,editor.md需要在github上下载好,放入webapp目录即可。

需注意:以上效果图只是基于前端代码,还未写入后端代码具体实现。

二、功能具体实现

1、数据库
(1)设计数据库

考虑到博客和用户两个实体,设计两张表。blogs表包括博客id、用户id、标题、时间、正文。users表包括用户id、密码、用户名。

(2)创建数据库表
create database if not exists blog_system charset utf8;
use blog_system;
drop table if exists blogs;
create table blogs (
    blogid int primary key auto_increment,
    useid int,
    title varchar(1024),
    postTime datetime,
    content varchar(4096)
);
drop table if exists users;
create table users(
    useid int primary key auto_increment,
    username varchar(50) unique,
    password varchar(50)
);
insert into blogs values (1 ,1, '这是第一篇博客',now(), '# 从前天开始我要认真写代码');
insert into blogs values (2, 1, '这是第二篇博客', now(), '# 从昨天开始我要认真写代码');
insert into blogs values (3, 1, '这是第三篇博客', now(), '# 从今天开始我要认真写代码');
insert into users values (1, 'gyn', '123');
insert into users values (2, 'gyq', '000');

(3)实现对blogs表和users表的操作并封装

①blog类对应的对象即为blogs表的每条数据

package model;

import java.sql.Timestamp;

public class blog {
    private int blogid;
    private int useid;
    private String title;
    private String content;
    private Timestamp postTime;

    public int getBlogid() {
        return blogid;
    }

    public void setBlogid(int blogid) {
        this.blogid = blogid;
    }

    public int getUseid() {
        return useid;
    }

    public void setUseid(int useid) {
        this.useid = useid;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public Timestamp getPostTime() {
        return postTime;
    }

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

    @Override
    public String toString() {
        return "blog{" +
                "blogid=" + blogid +
                ", useid=" + useid +
                ", title='" + title + '\'' +
                ", content='" + content + '\'' +
                ", postTime=" + postTime +
                '}';
    }
}

②user类对应的对象即为user表中的每条数据

package model;

public class user {
    private int useid;
    private String username;
    private String password;

    public int getUseid() {
        return useid;
    }

    public void setUseid(int useid) {
        this.useid = useid;
    }

    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;
    }

    @Override
    public String toString() {
        return "user{" +
                "useid=" + useid +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

③建立数据库连接和释放资源

获取数据源时,可以考虑使用单例模式中的懒汉模式。又考虑到懒汉模式是线程不安全的,且一个服务器会处理不同客户端的请求,所以需要加锁。

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 volatile DataSource dataSource=null;
    public 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("272222");
                }
            }
        }
        return dataSource;
    }
    
    public static Connection getConnection() throws SQLException {  //建立连接
        return getdataSource().getConnection();
    }
    
    //释放资源
    public static void close(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet){
        if(resultSet==null){   
            try {
                resultSet.close();
            }catch (SQLException e){
                throw new RuntimeException();
            }
        }
        if(preparedStatement==null){
            try {
                preparedStatement.close();
            }catch (SQLException e){
                throw new RuntimeException();
            }
        }
        if(connection!=null){
            try {
                connection.close();
            }catch (SQLException e){
                throw new RuntimeException();
            }
        }
    }
}

④针对blogs表的一些操作

获取blogs表全部信息 -- 显示博客列表页;

根据blogid查找博客 -- 显示博客详情页;

增加博客 -- 发布博客。

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 blogDo {
    //获取blog表全部信息--显示博客列表页需要
    public List<blog> getblogs(){
        List<blog> list=new ArrayList<>();
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;
        try {
            connection=DBUtil.getConnection();
            String sql="select * from blogs order by postTime desc"; //根据时间降序
            preparedStatement=connection.prepareStatement(sql);
            resultSet=preparedStatement.executeQuery();
            while (resultSet.next()){
                blog blog1=new blog();
                blog1.setBlogid(resultSet.getInt("blogid"));
                blog1.setUseid(resultSet.getInt("useid"));
                blog1.setPostTime(resultSet.getTimestamp("postTime"));
                blog1.setTitle(resultSet.getString("title"));
                blog1.setContent(resultSet.getString("content"));
                if(blog1.getContent().length()>=20){  //
                    blog1.setContent(blog1.getContent().substring(0,21)+"......");
                }
                list.add(blog1);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            DBUtil.close(connection,preparedStatement,resultSet);
        }
        return list;
    }
    //根据blogid查找blog信息--显示博客详情页需要
    public blog getblog(int blogid){
       Connection connection=null;
       PreparedStatement preparedStatement=null;
       ResultSet resultSet=null;
       blog blog1=new blog();
       try {
           connection=DBUtil.getConnection();
           String sql="select * from blogs where blogid=?";
           preparedStatement=connection.prepareStatement(sql);
           preparedStatement.setInt(1,blogid);
           resultSet=preparedStatement.executeQuery();
           if(resultSet.next()){
               blog1.setContent(resultSet.getString("content"));
               blog1.setTitle(resultSet.getString("title"));
               blog1.setPostTime(resultSet.getTimestamp("postTime"));
               blog1.setUseid(resultSet.getInt("useid"));
               blog1.setBlogid(resultSet.getInt("blogid"));
           }
       } catch (SQLException e) {
           throw new RuntimeException(e);
       }finally {
           DBUtil.close(connection,preparedStatement,resultSet);
       }
       return blog1;
    }
    //增加blog--发布博客需要
    public void addblog(blog blog1){
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;
        try {
            connection=DBUtil.getConnection();
            String sql="insert into blogs values(null,?,?,now(),?)";
            preparedStatement=connection.prepareStatement(sql);
            preparedStatement.setInt(1,blog1.getUseid());
            preparedStatement.setString(2,blog1.getTitle());
            preparedStatement.setString(3,blog1.getContent());
            preparedStatement.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            DBUtil.close(connection,preparedStatement,resultSet);   
        }
    }
}

⑤针对users表的一些操作

根据username获取用户信息 --博客列表页显示用户信息;

根据useid获取用户信息 --博客详情页显示用户信息;

根据username获取密码 --登陆检验密码是否正确。

package model;

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

public class userDo {
    //1、根据username获取用户信息 --博客列表页显示用户信息
    public user getuser(String username){
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;
        user user1=new user();
        try {
            connection=DBUtil.getConnection();
            String sql="select * from users where username=?";
            preparedStatement=connection.prepareStatement(sql);
            preparedStatement.setString(1,username);
            resultSet=preparedStatement.executeQuery();
            if(resultSet.next()){
                user1.setUseid(resultSet.getInt("useid"));
                user1.setUsername(resultSet.getString("username"));
                user1.setPassword(resultSet.getString("password"));
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return user1;
    }
    //2、根据useid获取用户信息 -- 博客详情页显示用户信息
    public user getuser(int useid){
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;
        user user1=new user();
        try {
            connection=DBUtil.getConnection();
            String sql="select * from users where useid=?";
            preparedStatement=connection.prepareStatement(sql);
            preparedStatement.setInt(1,useid);
            resultSet=preparedStatement.executeQuery();
            if(resultSet.next()){
                user1.setUseid(resultSet.getInt("useid"));
                user1.setUsername(resultSet.getString("username"));
                user1.setPassword(resultSet.getString("password"));
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            DBUtil.close(connection,preparedStatement,resultSet);
        }
        return user1;
    }
    //3、根据username获取用户密码 -- 登陆需要
    public String getpassword(String username){
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;
        String password=null;
        try {
            connection=DBUtil.getConnection();
            String sql="select * from users where username=?";
            preparedStatement=connection.prepareStatement(sql);
            preparedStatement.setString(1,username);
            resultSet=preparedStatement.executeQuery();
            if(resultSet.next()){
                password=(resultSet.getString("password"));
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            DBUtil.close(connection,preparedStatement,resultSet);
        }
        return password;
    }
}
2、登陆功能实现
(1)客户端发送请求

请求路径:/login,方法为post,内容为form表单形式

username="username"&password="password"

(2)服务器接收请求并做出响应

(3)效果

3、显示博客列表页
(1)客户端发送请求

请求路径:/blog;方法:get方法;格式:json

(2)服务器接收请求并做出响应

(3)客户端收到响应后显示在页面上

类似前端这种效果:

代码实现:

(4)效果

发现时间的格式是按时间戳的形式,不是按年--月--日的格式,得调整。需要确定是不是服务器做出响应时就是时间戳的形式。

抓包响应的正文:

抓包发现服务器做出响应的正文就是按时间戳的形式,得修改数据库该属性的返回形式。Java 标准库提供了一个 SimpleDateFormat 类, 完成时间戳到格式化时间的转换

4、显示博客详情页
(1)客户端发送请求

请求路径:/blog?blogid="blogid";请求方法:get;请求格式:json

查看全文时,跳转到一个链接:

 博客详情页发送get请求时包含blogid 

(2)服务器接收请求并做出响应

(3)客户端收到响应后显示在页面上

类似前端这种效果:

实现代码:

(4)效果

发现上面显示的内容不是按照md后的格式,而是md的原始数据,需要渲染为html

引入editor库:

改变html的正文标签内容:

 效果图:

5、显示列表页用户信息
(1)客户端发送请求

显示博客列表页的同时也要显示列表页用户信息。

请求路径:/userinfo;请求方式:get;请求类型:json。

(2)服务器接收请求并做出响应

(3)客户端收到响应后显示在页面

只需改变前端代码的用户名

实现代码:

(4)效果

登陆gyq账号:

6、显示详情页用户信息
(1)客户端发送请求

显示博客详情页的同时也要显示详情页用户信息。

请求路径:/autherinfo;请求方式:get;请求类型:json。

(2)服务器接收请求并做出响应

(3)客户端收到响应后显示在页面

(4)效果

7、发布博客
(1)客户端发送请求

点击“写博客”按钮时,页面会跳转,在跳转页面发送请求。

请求路径:/blogs;请求方法:post;请求类型:form;title="title"&content="content";

(2)服务器接收请求并做出响应

(3)效果

8、强制要求登陆

在进入页面时,要求用户必须登陆,每个页面发送请求判断是否已经登陆,没有登陆跳转到登陆页面进行登陆。

(1)客户端发送请求

请求路径:/force;请求方法:get;请求类型:json;

(2)服务器接收请求并做出响应
(3)效果

在未登陆情况下点击主页或写文章都会跳转到博客登录页面。

9、退出登陆
(1)客户端发送请求

点击注销会跳转到logout路径下,发起请求

(2)服务器处理请求 并做出响应

(3)效果

点击注销按钮,页面会跳转到博客登录页面。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

筑梦前行!苏州金龙荣获影响中国客车业两项大奖

2024年1月19日&#xff0c;第十八届影响客车业年度盘点颁奖典礼在合肥举行。活动期间&#xff0c;众多奖项如期揭晓&#xff0c;经组委会评审团评定&#xff0c;苏州金龙海格睿星KLQ5041XSWEV1、旅行家KLQ6127YEV1N分别荣获“定制旅游客车之星”大奖和“新能源客车推荐车型”大…

搜索引擎Elasticsearch了解

1.Lucene 是什么? 2.模块介绍 Lucene是什么: 一种高性能,可伸缩的信息搜索(IR)库 在2000年开源,最初由鼎鼎大名的Doug Cutting开发 是基于Java实现的高性能的开源项目 Lucene采用了基于倒排表的设计原理,可以非常高效地实现文本查找,在底层采用了分段的存储模式,使它在读…

Your lDE is missing natures to properly support your projects

错误提示 Your lDE is missing natures to properly support your projects. Some extensions on the Eclipse Marketplace can be installed to support those natures.解决方案 打开项目文件&#xff0c;找到.project 文件&#xff0c;用编辑器打开 找到 把下图效果图中相关…

【方法重写】精英必看:详解Java中的方法重写!!

前言 当我在学到“面向对象”这块内容的时候&#xff0c;学到了一个概念&#xff0c;那就是“方法的重写”。重写又叫覆盖&#xff0c;英文名为“Override”。虽然”重写”、 ”覆盖”、“Override”这些名词都很容易记住&#xff0c;但很多人&#xff08;包括我&#xff09;并…

【数据库学习】pg安装与运维

1&#xff0c;安装与配置 #安装 yum install https:....rpm1&#xff09;安装目录 bin目录&#xff1a;二进制可执行文件目录&#xff0c;此目录下有postgres、psql等可执行程序&#xff1b;pg_ctl工具在此目录&#xff0c;可以通过pg_ctl --help查看具体使用。 conf目录&…

Journal of Intelligent Fuzzy Systems期刊的格式要求

摘要 摘要应该清晰、具有描述性&#xff0c;自说明&#xff0c;并且不超过200字。同时&#xff0c;它应该适合在文摘服务中发布。请在摘要中不要包含参考文献或公式。 关键词&#xff1a;关键词一&#xff0c;关键词二&#xff0c;关键词三&#xff0c;关键词四&#xff0c;关…

电商API接口接入|电商爬虫实践附代码案例

1.爬虫是什么 首先应该弄明白一件事&#xff0c;就是什么是爬虫&#xff0c;为什么要爬虫&#xff0c;百度了一下&#xff0c;是这样解释的&#xff1a;网络爬虫&#xff08;又被称为网页蜘蛛&#xff0c;网络机器人&#xff0c;在FOAF社区中间&#xff0c;更经常的称为网页追…

银行数据仓库体系实践(6)--调度系统

调度系统是数据仓库的重要组成部分&#xff0c;也是每个银行或公司一个基础软件或服务&#xff0c;需要在全行或全公司层面进行规划&#xff0c;在全行层面统一调度工具和规范&#xff0c;由于数据类系统调度作业较多&#xff0c;交易类系统批量优先级高&#xff0c;为不互相影…

算法------(10)堆

例题&#xff1a;&#xff08;1&#xff09;AcWing 838. 堆排序 我们可以利用一个一维数组来模拟堆。由于堆本质上是一个完全二叉树&#xff0c;他的每个父节点的权值都小于左右子节点&#xff0c;而每个父节点编号为n时&#xff0c;左节点编号为2*n&#xff0c;右节点编号为2*…

10. UE5 RPG使用GameEffect创建血瓶修改角色属性

前面我们通过代码实现了UI显示角色的血量和蓝量&#xff0c;并实现了初始化和在数值变动时实时更新。为了测试方便&#xff0c;没有使用GameEffect去修改角色的属性&#xff0c;而是通过代码直接修改的数值。 对于GameEffect的基础&#xff0c;这里不再讲解&#xff0c;如果需要…

跨境电商的网络为什么要用云桥通SDWAN企业组网?

传统的WAN连接通常由交换机和路由器构成&#xff0c;然而&#xff0c;随着企业内部网络的扩张和变革&#xff0c;传统WAN的管理和配置变得复杂繁琐。云桥通SDWAN组网采用了较新的技术方式&#xff0c;通过中央控制器对局域网设备进行管理和配置&#xff0c;从而实现了更为灵活、…

Java工程师的你,真的不想了解一下《类文件结构》吗?

身为Java工程师的你&#xff0c;真的不想了解一下《类文件结构》吗&#xff1f; 文章目录 身为Java工程师的你&#xff0c;真的不想了解一下《类文件结构》吗&#xff1f;回顾一下字节码Class 文件结构总结魔数&#xff08;Magic Number&#xff09;Class 文件版本号&#xff0…

彩虹PLM系统 产品数据管理解决方案

彩虹PLM系统 产品数据管理解决方案 当企业面临以下问题时&#xff0c;可能需要考虑引入 彩虹PLM系统&#xff1a; 随着市场竞争的日益激烈&#xff0c;企业需要不断提高自身的竞争优势和生产效率。然而&#xff0c;许多企业在产品研发、生产和管理方面仍然面临着诸多挑战。 例…

应急响应-Windows-进程排查

进程&#xff08;process&#xff09;是计算机中的程序关于某数据集合上的一次运动活动&#xff0c;是系统进行资源分配和调度的基本单位&#xff0c;是操作系统结果的基础。在早期面向进程结构中&#xff0c;进程是线程的容器。无论是在Windows系统还是Linux系统中&#xff0c…

探索二手旧物回收小程序:环保与经济的完美结合

随着社会的进步和人们生活水平的提高&#xff0c;消费观念也在不断变化。然而&#xff0c;在追求时尚和品质的同时&#xff0c;我们也面临着资源浪费和环境污染的问题。为了解决这些问题&#xff0c;二手旧物回收小程序应运而生。 一、二手旧物回收小程序的背景和意义 随着消…

小程序 样式 WXSS

文章目录 样式 WXSS尺⼨单位样式导⼊选择器⼩程序中使⽤less 样式 WXSS WXSS( WeiXin Style Sheets )是⼀套样式语⾔&#xff0c;⽤于描述 WXML 的组件样式。 与 CSS 相⽐&#xff0c;WXSS 扩展的特性有&#xff1a; 响应式⻓度单位 rpx样式导⼊ 尺⼨单位 rpx &#xff08;…

滴滴基于 Ray 的 XGBoost 大规模分布式训练实践

背景介绍 作为机器学习模型的核心代表&#xff0c;XGBoost 在滴滴众多策略算法业务场景中发挥着至关重要的作用。因此&#xff0c;保障并持续提升 XGBoost 模型的离线训练及在线推理稳定性一直是机器学习平台的重点工作。同时&#xff0c;面对多样化的业务场景定制需求和数据规…

Matlab图像增强学习笔记——imadjust函数的使用

1.引言 图像增强是数字图像处理领域中的一个重要主题&#xff0c;它涉及改进图像的对比度、亮度和色彩等方面&#xff0c;以使图像更适合于特定应用或更易于分析。Matlab 提供了丰富的图像处理工具&#xff0c;其中 imadjust 函数是一种强大的图像增强工具。本篇文章将深入学习…

年老返乡难,凭君传语报平安

惧于媒体谎言多&#xff0c;浏览社交媒体发布的国内外五花八门的时事新闻报道&#xff0c;踯躅良久&#xff0c;笔者放弃选择话题置评&#xff0c;只得履行本“人民体验官”义务&#xff0c;推广人民日报官方微博文化产品《你好&#xff0c;回家&#xff01;》&#xff0c;敷衍…

【Java网络编程03】网络原理进阶

【Java网络编程03】网络原理进阶 1. UDP协议 1.1 基本介绍 我们首先再来回顾UDP协议的基本特点&#xff1a; 无连接的不可靠传输的面向数据报的全双工的 既然谈到数据报&#xff0c;我们就来看一下UDP数据报的格式&#xff1a; UDP数据报分为报头和载荷部分&#xff0c;其…