【博客系统】 一

news2025/2/27 1:50:22

该博客系统基于servlet和mysql数据库 , 并且通过xshell终端工具部署至云服务器. 实现的功能包括:

1.博客列表页

2.博客详情页

3.登陆页面

4.强制登陆检查

5.获取用户信息

6.退出登陆

7.发布博客

一.系统展示

登陆页面

博客列表页

博客详情页

博客编辑页


下面就开始编写代码了. (前端代码不提供) 接下来的操作主要是两个大的方面 . 

1.前端和服务器的交互

2.服务器和数据库的交互

二.服务器和数据库的交互

该系统涉及的表包括blog博客表和用户登陆的user表. 

一般需要把建库建表的操作,写成sql文件保留下来 , 后续如果把程序部署到别的机器上,建库操作直接赋值sql,然后执行就可以完全服务器数据库的建库建表操作.

dao层

Data Acess Object 数据访问对象 , 写一些类,通过这些类里的方法封装了数据库操作,此时数据库就是通过这样的对象来访问的

1.设计数据库

  • 根据需求,找出需要有哪些实体
  • 梳理清楚实体和实体之间的关系 一对一/一对多/多对多

2.封装DBUtil 实现建立连接和断开连接

package dao;


import com.mysql.cj.jdbc.MysqlDataSource;

import javax.sql.DataSource;
import javax.xml.transform.Result;
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;

    //私有,只在类内使用
    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:13306/blogsystem?characterEncoding=utf8&useSSL=false");
                    ((MysqlDataSource) dataSource).setUser("root");
//                    ((MysqlDataSource) dataSource).setPassword("chenyafen");
                    ((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) throws SQLException {


        if(resultSet!=null){
            resultSet.close();
        }

        if(statement!=null){
            statement.close();
        }

        if(connection!=null){
            connection.close();
        }
    }

}

3.创建实体类 后续数据库操作是围绕实体类展开的

三.服务器和数据库的交互

实现前后端交互逻辑 , 针对每个功能点的步骤都是一样的. 

1.设计前后端交互接口

2.开发后端代码

3.开发前端代码

4.调试

1.博客列表页

让博客列表页再加载的时候,发起一个ajax的http 请求,请求发送到服务器上,就能获取博客列表数据. 进一步的把博客数据展示到页面上 (拼接成一些html片段)

1.前端发起一个http请求,向后端索要博客列表数据

2.后端收到请求之后查询数据库获取到数据库中的博客列表,返回给前端

3.前端拿到响应之后,就依据这里的内容,构造出html片段,最终显示出来

在进行这三个操作之前,还需要约定前后端交互接口,后续前端和后端要进行很多不同的数据交互.每一种数据交互,都需要发送不同的请求,返回不同的响应 .

此处就需要把请求具体什么样? 响应具体什么样? 都约定好 !

约定前后端交互接口

以下是一种典型的约定方式

请求:

GET blog

响应:

HTTP/1.1 200 OK

Content-Type:application/json ( 返回的是json数据)

[

        {

                blodId:1,

                title:"第一篇",

                content:"dddd",

                userId:1,

                posttime:"ddddd"

        } ,

        {

                blodId:1,

                title:"第一篇",

                content:"dddd",

                userId:1,

                posttime:"ddddd"

        }

]

前端负责构造请求 , 解析响应 ;

后端负责解析请求, 构造响应 ;

编写后端代码

api应用编程接口

博客系统后续还会写一些servlet给前端提供功能的支持. 这些都可以理解成服务器给前端提供的api (或者也可以叫做Controller )

说明:

jackson看到blogs是一个list,就会构造出一个json数组; 针对list中每一个blog对象,分别构造出json对象 , 具体构造过程,就是根据Blog属性:属性的名字就是json的key,属性的值就是json的值

 

编写前端代码

让页面通过js ajax的方式发起http请求 . 

说明:

1.定义了一个函数,并调用这个函数 (不需要返回值)

2.构造这个html片段

相当于

<div> </div>

<div class="blog"> <div>

blog就是服务器返回的json数组里的一个元素 (这一个元素有五个属性)

浏览器访问该页面

 Fiddler抓包

上面的请求是获取列表页这个静态页面的

下面的请求是获取博客数据的

如果出现灰色的是因为触发了浏览器自带的缓存;

浏览器为了提高页面加载速度,就会把静态的资源在本地硬盘缓存一份,后续再访问统一资源,直接从本地获取 .

前后端交互过程:

当浏览器发起一个形如blog的http请求时,服务器就会调用查询数据库,并获取到数据库中的数据,然后转换为json格式的字符串,再返回给前端,前端拿到数据之后,回调函数进行遍历数据,依据返回的数据构造出html片段

问题:

1.更早发布的博文应该在下面 .

解决方法:给查询语句加上order by ,按照时间降序排序(大的在前, 小的在后)即可

2.时间格式不对

针对这个问题,要先明确问题出在前端还是后端 , 抓包查看后端返回的响应 , 发现是后端的问题

后端将从数据库读取到的对象转换为json字符串,转成的json字符串就是根据Blog对象的getter方法来完成的 ,jackson会自动调用getter方法把得到的结果作为json字符串中属性的值.  因此问题出在posttime的getter方法上,

使用simpleDateFormat方法:

2.博客详情页

2.1.约定前后端交互接口

请求:

GET  /blog?blodId=1     

如果是请求中不带query string, 此时就是查询博客列表

如果带有query string (blogId) , 此时就是查询指定博客的详细情况

响应:

HTTP/1.1 200 OK

Content-Typea:application/json

{

    blogId:1,

    title:"dfljf",

    content:"gjdsf",

    userId:1,

    posttime:"2023-12-4"

}

2.2实现后端代码

2.3实现前端代码

注意:

1.这里需要让博客详情页,把数据库的中的原始数据,渲染成md渲染后的数据

使用editor.md的线程的方法即可(阅读文档)

2.editor.md也依赖jquery,注意引入的顺序

3.登陆页面

3.1前后端交互接口

请求:

POST /login

Content-type:aaplication/x-www-form-urlencoded

使用form表单提交 使用ajax也可以

响应:

HTTP/1.1 302

Location:blog_list.html

3.2编写后端代码

注意:

1.不要对用户名和密码分别提示,容易造成不安全

2.创建会话,参数设为true.

不存在会话就创建,存在就查询 ;  并且会生成键值对 (sesesionid : httpsession对象 ), 并且会把session通过set-cookie返回到浏览器

3.3编写前端代码

注意:

1.构造sql语句的时候 , 先用preparestatement创建statement . 再设置占位符的值

否则会出现空指针异常

4.实现强制登陆

使得网站登陆后才能使用, 此处咱们要求我们的博客系统,必须登陆才能使用 ;

如果用户在未登陆情况下,访问博客列表页/详情页/编辑页,都会自动跳转到登录页

4.1约定前后端交互接口

在博客列表页/详情页/编辑页,再发起一个get的ajax请求,询问服务器时候登陆

4.2编写前后端代码


5.实现显示用户信息

在列表页,显示当前登陆用户的个人信息 ; 在详情页,显示这个文章的作者信息

实现方法:

在博客列表页和详情页分别发起ajax请求

列表页,就需要获取到当前登陆用户的信息 ; 详情页,就需要获取到文章作者的信息.

5.1约定前后端交互接口

列表页

请求:

GET /user

响应:

HTTP/1.1 200 ok

{

    userId:1,

    username:'zhangsan'

}

详情页

请求:

GET /user?blogId=1

响应:

HTTP/1.1 200 OK

{

    userId:1,

    username:'zhangsan'

}

注意:

对于登陆功能来说,依赖了session机制,tomcat是在内存中存储session的.

当重启了tomcat服务器之后,之前的session就没了,下一次访问就需要重新登陆

但是有些smart tomcat会把session放到硬盘中持久化存储 , 重启服务器也不需要重新登陆 ;

6.退出登陆(注销)

判定登陆状态逻辑中

1.会话存在

2.会话中存储的user对象存在

两个条件同时满足,才认为用户是已经登陆了

破坏上述任何一个条件都可以实现注销

但是servlet中,并没有提供一个api来直接删除会话,但是有api可以删除会话中的user

(Attribute)

6.1约定前后端交互接口

请求:

GET /logout 

响应:

HTTP/1.1 302

Location :login.html

6.2后端

6.3前端

点击页面的注销,实质上是一个a标签,通过a标签的href属性,指定要访问的请求路径即可 .

点击a标签,自然就能触发http get请求了

7.发布博客

本质上和登陆差不多, 核心都是通过form表单,把页面中用户输入的内容提高到服务器,服务器就会内容保存到数据库中.

7.1约定前后端交互接口

使用form提交数据到服务器

请求:

POST /blog

Conten-type:application/x-www-form-urlencoded (form表单格式)

body内容:

title=***&content=***** 

响应:

HTTP/1.1 302

Location:blog_list.html

提交成功跳转到博客列表页,来到页表页之后,就能够看到刚才新发布的博客了 .

7.2后端

7.3前端

把form表单补齐

注意:

md编辑器怎么添加name属性呢?

在此处写一个隐藏的textarea,就可以实现form表单提交的效果,就可以指定name的值.


部署请看这篇 【博客系统】 二-CSDN博客 ~~~ 

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

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

相关文章

【Proteus仿真】【STM32单片机】锂电池管理系统

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真STM32单片机控制器&#xff0c;使用LCD1602显示模块、DS18B20温度传感器、PCF8691 ADC模块、按键、LED蜂鸣器模块等。 主要功能&#xff1a; 系统运行后&#xff0c;LCD1602显示温…

Java方法中不使用的对象应该手动赋值为NULL吗?

在java方法中&#xff0c;不使用的对象是否应该手动赋值为null&#xff1f;我们先来通过一个示例看一下。 垃圾回收示例一 public class GuoGuoTest {public static void main(String[] args) {byte[] placeholder new byte[64 * 1024 * 1024];System.gc();} } 上面代码向内…

第五章 路由技术及应用

目录 5.1 直连路由概述 5.1.1 直连路由工作原理 5.1.2 直连路由配置 5.2 直连路由仿真 5.3 静态路由技术 5.3.1 静态路由定义 5.3.2 静态路由工作原理 5.3.3 静态路由配置 5.3.4 默认路由 (1) 默认路由概述 (2) 配置默认路由 (3) 默认路由应用场合&#xff1a;上网…

QGIS之二十四安装插件

1、从菜单栏中找到插件 2、搜索插件 从搜索框中搜索插件&#xff0c;如“cesium" 3、安装插件 4、查看插件 安装好的插件从这边可以看到&#xff0c;当然&#xff0c;其它插件可能在其它位置 5、已安装插件 可以查看已安装的插件

050-第三代软件开发-软件部署脚本(二)

第三代软件开发-软件部署脚本(二) 文章目录 第三代软件开发-软件部署脚本(二)项目介绍软件部署脚本(二) 关键字&#xff1a; Qt、 Qml、 bash、 shell、 脚本 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&#xff08;Qt Meta-Object Languag…

界面组件DevExpress Reporting v23.1亮点 - 全新升级报表查看器

DevExpress Reporting是.NET Framework下功能完善的报表平台&#xff0c;它附带了易于使用的Visual Studio报表设计器和丰富的报表控件集&#xff0c;包括数据透视表、图表&#xff0c;因此您可以构建无与伦比、信息清晰的报表 界面组件DevExpress Reporting v23.1已经发布一段…

pyclipper和ClipperLib操作多边型

目录 1. 等距离缩放多边形 1.1 python 1.2 c 1. 等距离缩放多边形 1.1 python 环境配置pip install opencv-python opencv-contrib-python pip install pyclipper pip install numpy import cv2 import numpy as np import pyclipperdef equidistant_zoom_contour(contour…

k8s pod常用运维命令

1. 概述 kubectl 命令是操作 Kubernetes 集群的最直接和最高效的途径&#xff0c;熟练掌握命令的使用能起到事半功倍的效果&#xff0c;整理命令有助于加深记忆&#xff0c;该文仅记录关于pod常用的操作运维命令。 2. 查看namespaces 查看k8s集群中目前存在的namespaces kub…

使用VC++设计程序使用邻域平均平滑算法、中值滤波算法、K近邻均值滤波器(KNNF)进行滤波

VC实现若干种图像滤波技术 文章目录 VC实现若干种图像滤波技术实验内容邻域平均平滑算法1. 原理2. 实验代码3. 实验现象 中值滤波算法1. 原理2. 实验代码3.实验现象 K近邻均值滤波算法&#xff08;KNNF&#xff09;1. 原理2. 实验代码实验现象 实验内容 实验要求&#xff1a; …

深入了解域名与SSL证书的关系

在如今数字化的世界里&#xff0c;网络安全成为我们关注的重要议题之一。为了确保数据在网络上传输的安全性&#xff0c;我们通常会采取各种安全措施&#xff0c;其中最常用的就是SSL证书。然而&#xff0c;很多人并不了解SSL证书是如何与域名相互关联的。 首先&#xff0c;我…

TensorFlow案例学习:图片风格迁移

准备 官方教程&#xff1a; 任意风格的快速风格转换 模型下载地址&#xff1a; https://tfhub.dev/google/magenta/arbitrary-image-stylization-v1-256/2 学习 加载要处理的内容图片和风格图片 # 用于将图像裁剪为方形def crop_center(image):# 图片原始形状shape image…

基于风驱动算法优化概率神经网络PNN的分类预测 - 附代码

基于风驱动算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于风驱动算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于风驱动优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神经网络…

Java排序算法之归并排序

图解 归并排序是一种效率比较高的分治排序算法&#xff0c;主要分为两个步骤&#xff0c;分别为“分”和“并”。 分&#xff1a;将序列不断二分&#xff0c;直到每个子序列只有一个元素为止。 并&#xff1a;将相邻两个子序列进行合并&#xff0c;合并时比较两个子序列的元素…

Vue3:给表格的单元格增加超链接功能(点击单元格可以跳转到新的页面)

一、目的 在Vue3项目中&#xff0c;给表格某个字段下的全部单元格添加超链接功能&#xff0c;点击对应的单元格可以进入对应的页面 二、定义单元格内容 使用ElementPlus的el-table组件来实现表格 1、代码 <template> <el-table :data"dataAll"> &…

LabVIEW进行MQTT通信及数据解析

需求&#xff1a;一般通过串口的方式进行数据的解析&#xff0c;但有时候硬件的限制&#xff0c;没法预留串口&#xff0c;那么如何通过网络的方式特别是MQTT数据的通信及解析 解决方式&#xff1a; 1.MQTT通信控件&#xff1a; 参考开源的mqtt-LabVIEW https://github.com…

TCP连接保活机制

在TCP连接中有一个保活机制&#xff0c;叫做Keep-Alive&#xff0c;用语言描述就是如下&#xff1a; 在保活时间内&#xff0c;如果没有任何连接相关的活动&#xff0c;TCP 保活机制会开始作用&#xff0c;每隔一个时间间隔&#xff08;保活时间间隔&#xff09;&#xff0c;发…

YOLOV8部署Android Studio安卓平台NCNN

下载Android Studio&#xff0c;配置安卓开发环境&#xff0c;这个过程比较漫长。 安装cmake&#xff0c;注意安装的是cmake3.10版本。 根据手机安卓版本选择相应的安卓版本&#xff0c;我的是红米K30Pro&#xff0c;安卓12。 使用腾讯开源的ncnn&#xff0c;这是一个为手机端极…

vue3实现数据大屏内数据向上滚动,鼠标进入停止滚动 vue3+Vue3SeamlessScroll

1.效果图 2.npm下载依赖及main.js文件配置 npm install vue3-seamless-scroll --saveimport vue3SeamlessScroll from vue3-seamless-scroll;app.use(vue3SeamlessScroll) 3.html代码 <!-- scrollFlag为true时再渲染,vue3只要涉及到传值子页面需要加flag判断&#xff0c;否…

阿里云今年服务器是真便宜,看看哪些云服务器值得买!

2023年双十一&#xff0c;阿里云推出了一项令人惊喜的独家优惠活动&#xff01;在这次活动中&#xff0c;阿里云开放了老用户购买权限&#xff0c;以超低的价格购买云服务器ECS经济型e实例。这款服务器配置了2核2G内存、3M固定带宽和40G ESSD entry系统盘。而且&#xff0c;更棒…

PDF文件中更改 PDF 文本颜色的最有效解决方案

PDF 是最常用的文档类型之一&#xff0c;也是商业中使用的首选文档。在工作中&#xff0c;我们经常需要修改PDF的文本内容&#xff0c;转换格式&#xff08;如PDF转Word&#xff0c;PDF转Excel等&#xff09;&#xff0c;合并PDF&#xff0c;以达到更好的工作效果。 然而&…