后端(四):博客系统项目

咱们在这里实现的是后端项目,前端代码就提一提,不全做重点介绍,在开始讲解这个博客系统项目之前,我们先看看这个项目的前端界面:

登录界面:

个人主页:

 博客详情页:

  写博客页:

 注销(回到登录页面):

编写博客系统后端操作

1. 准备工作

  1. 创建项目
  2. 引入依赖
  3. 创建必要目录

1. 创建项目

我们重新创建一个Maven项目,名叫blog_system

2. 引入依赖

我们该项目有几个必要的依赖,

  • 首先我们肯定是基于 Servlet 写代码的,所以 Servlet 一定需要引入。
  • 其次,我们这个项目不止有后端,还有前端,所以前后端之间会进行交互,其中后端要拿到前端传入的数据进行解析,这里解析就需要用到  jackson  (这个可以根据彼此之间的约定来确定究竟需要用到啥);我们这里约定就用 jackson  
  • 最后,我们最终的数据一定是保存在 数据库 中的,所以需要用到 JDBC ,我本机上用的又是 mysql 所以还需要引入 mysql 依赖。

我引入的版本如下:

3. 创建必要目录

上一章聊到的 web.xml 是每个项目都必须要用到的,这里再次提醒一下,随后就把我们前端的代码引入进来,如下图:

前端的代码放入在 webapp  目录之下就好。

具体的前端代码如下:

blog_system/src/main/webapp · wjm的码云/Projects

此外,我们在创建一个 sql 文件,该文件就存我们要对 数据库 初始化基本的操作;如建表,建库啥的。

2. 数据库设计

我们需要在这里 设计数据库结构,我们一共有几张表啊;每个表的数据是啥啊?

我们主要是针对需要储存的部分进行设计数据表。

其主要存储的就是 用户信息个人博客信息

用户信息

user:userId,username,password(还可以设置头像,用户的邮箱等等,这里设置的简单一点)

个人博客信息

blog:博客id,标题,正文,userId,发布时间

其中,具体的信息可以自己约定,这里为了方便,简单一点。

编写 数据库代码:

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

随便创建一个库,把字符集设置为 utf8 ,其次:

一般在创建表之前都会删一下,以防之前数据有残留,数据库一定是部署在一个新的机器上才会进行操作。

每次在新的机器上都需要操作一遍,故此我们将建好的数据库保存在.db文件下

3.  创建 博客类对象和 用户对象

我们先创建一个包,将数据库的封装和需要创建的实体类都存放在这里(包名可以随便起):

针对上述数据库设计的表,我们需要设计两个相对应的类。

一个叫做 Blog 类,一个叫做 User 类,分别对应 个人博客信息 用户信息

Blog 类

博客表的设计如下:

博客id,标题,正文,userId,发布时间

故此,我们类的设计也一样:

而后,加上 set 和 get 方法:

唯一一点需要注意的是:

User 类

用户表的设计如下:

user:userId,username,password

 步骤也和上面的 Blog 类一样:

4. 数据库的封装

这一步就是连接数据库:

我们在哪些地方可能会用到 数据库呢?

  • 把一个 Blog 对象插入到数据库中
  • 查询 blog 表中所有的博客数据
  • 指定一个博客id 来查询对应的博客
  • 指定 博客id 来删除博客
  • 通过用户id 来查询用户
  • 通过用户名来查询用户

我们将其分为两类,一个是 博客相关的,一个是与用户相关的

在做这两个类之前,我们还需要写一个JDBC,通过这个类,封装数据库的连接操作:

DBUtil

就是经典的连接数据的操作;我们这里将 DataSource 设置为单例的(这里可以设置为其他的):

省的每次都需要去重新连一遍,这里封装好,其他需要就直接调用就好了。

除了连接数据库,还必须带有关闭连接的方法,光连接不断开连接,会造成连接空耗,后面的连接又无法进来,这就造成了资源的极大浪费

所以,关闭连接是必须的:

 既然创建好了,就可以调用,所以还有一个 getConnection 方法:

具体的代码连接如下:

blog_system/src/main/java/module/DBUtil.java · wjm的码云/Projects - 码云 - 开源中国 (gitee.com)

UserDao

DAO全称Data Access Object,意思是数据访问对象.在java服务器开发的三层架构中分成控制层(Controller),表示层(service),数据访问层(dao),数据访问层专门负责跟数据库进行数据交互.

selectUserById:

selectUserByName:

 这个方法几乎和上述ById 一样,只是有微调

BlogDao

根据上述可能会用到的四种情况分别设计相应的方法:

  1.   把一个 Blog 对象插入到数据库中
  2.   查询 blog 表中所有的博客数据
  3.  指定一个博客 id 来查询对应的博客
  4.  指定博客id 来删除 博客

我们先来个最简单的删除操作;

删除

我们的大致思路就是根据 博客id 来删除某篇博客:

查询单篇博客

 大致思路就是:从数据库中根据这篇博客的 id 找到,在new 一个Blog 对象,将找到的数据都放到这个 Blog 对象上去,最后返回这个对象:

 找不到就返回 null;

查询所有博客

大致思路就是:按照时间的顺序,将博客呈现到页面上 

我们需要而外注意这一段:

这里给博客进行了一个截取 

如果是这种正文很短的那就不需要截取, 

类似于这种长的,不截取页面会一口气呈现出来。

这就和上面查询单片博客的操作类似。

插入

 就是个JDBC + sql 操作

 我们从上述多个方法中可以看到,JDBC 其实都不难,就是啰嗦, Connection 等 每个方法都要出现一次,这也是后面框架必学的原因,框架就很好的简化了这些步骤。

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

因为这一步开始编写后端代码了,所以我们在创建一个新的包,名字随便起,主要是和数据库 代码的以示区分

博客列表页

展示博客列表

1)约定前后端交互接口

 2)编写后端代码

 写一个 Servlet,主要是用来处理一类 HTTP 请求,加上 Servlet 都需要继承 HttpServlrt 父类,再加上一个 WebServlet 注解(描述了哪个路径和这个类相关)。

创建一个 Servlet 来处理相对应的请求

 我们当前的请求是这样的:

 可以通过修改id的请求来跳转页面

 不传入 id 就默认是加载所有的 博客。

 3)编写前端代码

构造 ajxa 请求,按照上述约定,发送 http 请求

 前端代码要做的事,就是根据咱们当前这个页面的结构构造出来的,页面是啥样,前端就怎么构造

前端部分可以不理解,我们重点还是在后端代码上。

登录功能

输入用户名 和 密码,点击登录就可以实现登录功能。

期望:点击登录之后,给后端发送一个http 请求,后端接收到请求以后,作出一些处理逻辑(包括验证用户名和密码啥的)

一般这一段的逻辑大部分都是进行 验伪 操作 。

1)约定前后端交互接口

2)编写后端代码

创建一个 Servlet 来处理 login 的请求

如果全段传过来的用户名带有中文,此时的代码拿到的 username 可能是乱码,需要提前设置一下编码方式:

 事实上,每个网站在处理验伪的过程中都不会告诉你具体是哪一块 出错了,而是直接给你返回一个用户名或密码错误,防止你猜对。

 当然啦,我们在编写后端,为了方便自己找 bug 还是可以以示区分的:

验证完用户名密码以后,我们将其保存在会话中,现在在很多大的电商平台等都是这么设置的,例如:淘宝。

我们在网页上浏览淘宝时都需要扫码登陆,着就是个会话,没有这个会话你就无法继续访问,于是他就会弹出一个对话框,必须登录...

我们这里也设置一个会话,让服务器保存当前用户的一些数据~

会话就可以理解为一个哈希表,灭个用户(每个客户端)都会对应到这个表里的一个键值对。其中键是一个字符串,sessionId(唯一的字符串),其中值是 HttpSession对象。

此后,我们其他的页面功能都需要添加一个验证 会话是否存在的功能,此功能不存在就回到登录页面,重新登录。

3)编写前端代码

此外,我们还需要编写判断登录的代码:

强制要求用户登录,检查用户的登录信息

我们在我们这项目中设定:

当用户访问 博客列表页、详情页、编辑页 的时候,必须要是登陆的状态,如果未登录就跳转到登录页面。

当用户访问 博客列表页、详情页、编辑页 的时候,发起一个 ajax 请求,用户获取当前的用户信息是否以登录。

1)约定前后端交互接口

2)编写后端代码

我们就写在 登录代码一起好了,反正都是两个方法,一个是 get 一个是 Post

3)编写前端代码

页面要通过 ajax 发起请求,获取登录状态信息

首次运行的时候,好像没有触发到这里的检查登录功能,大概率是浏览器缓存导致的,可以试着打开 Fiddler 并强制 刷新的时候,此时检查 登录 的功能就生效了。

因为我们在多个页面都用到了这个功能,所以我们可以单独写在一个 js 文件中,在需要到的页面调用一下即可。

 显示用户信息

1)约定前后端交互接口

在博客列表页,此处显示的是登录的用户的信息 :

在博客详情页,显示的是作者的信息 :

 在博客列表页中,要获取到登录用户 的信息,我们可以用上面 前端中 getLoginStatus 方法,让这个方法在登录成功之后就将 之前的用户信息给返回来。

2)编写后端代码

这里的代码就是上面 “会话” 代码的后半段:

当然,我这里只是返回了 用户名,至于其他的我这里暂时都没实现,后期空闲下来,我会继续完善这个博客系统(后期就不是在使用 Servlet 实现了,而是基于框架)。

3)编写前端代码

这个代码就是在 博客详情页代码中调用一下  getLoginStatus 方法就好。

博客详情页 

针对 博客详情页进行处理,详情页这里显示的是当前文章的作者信息,先根据 blogId ,查询到文章的对象,进一步拿到 作者 id,再根据 这个 id 查询作者名字,最终显示到页面上

1)约定前后端交互接口

 2)编写后端代码

我们新创建一个 Servlet 处理上述情况:

再获取信息的时候,我们绝大部分代码都在处理 验伪的操作:

用户退出功能(注销)

服务器收到这个 get请求,就可以把当前用户的 会话 中的 user 对象删除掉

 

1)约定前后端交互接口

2)编写后端代码

实现发布博客

此后,服务器就可以保存上述数据到数据库中,接下来后续就可以在博客列表页和博客详情页中看到 刚才的新博客

 1)约定前后端交互接口

  2)编写后端代码

 从请求中拿到标题和正文,从会话中拿到用户的登录信息和登录状态(作者id),并且获取到时间

前端代码这里就不展示了。

到这一个功能实现上述基本的功能就都实现了。

完整的代码我放在了我的码云下:

blog_system · wjm的码云/Projects - 码云 - 开源中国 (gitee.com)

我这个项目内置了一个 md 编辑器 ;  editor.md 这个包下的东西可以去下载:

链接:https://pan.baidu.com/s/1I3Kh2X0Xp1sygRU69qkRCg 
提取码:1234

直接将它拖入 你的idea 即可。

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

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

相关文章

常用API学习07(Java)

Date 在jdk1.8之前,java中的日期和时间是一类的,从1.8之后对日期和时间体系重新做了规划,划分出一个新的包 - java.time包,这个包中包含了日期、时间、时区、日历、单位。 Date,是java中最老的日期和时间类,后续退出…

Arcgis之 KML/KMZ文件转shp

一般我们在Goole Earth上勾画的区域导出后都为KML或者KMZ格式的,但无法在arcgis等软件上直接应用,故需进行一定的转换 1.打开ArcMap,选择ArcToolbox->Conversion Tools->From KML->KML To Layer 得到如下结果(由于本KML…

pytest自动化测试框架tep环境变量、fixtures、用例三者之间的关系

tep是一款测试工具,在pytest测试框架基础上集成了第三方包,提供项目脚手架,帮助以写Python代码方式,快速实现自动化项目落地。 在tep项目中,自动化测试用例都是放到tests目录下的,每个.py文件相互独立&…

自动驾驶分级和技术架构

标题SAE 和 NHTSA自动驾驶分级 当前全球汽车行业中两个最权威的分级系统由美国国家公路交通安全管理局(NHTSA)和国际自动化工程师协会(SAE)提出。2013年,NHTSA将驾驶自动化的描述分为5个层级。2014年1月,SAE制定J3016自动驾驶分级…

Mybatis基础模块-日志管理

文章目录 1. 适配器模式2. Log2.1 默认实现StdOutImpl2.2 Log4jImpl 3. LogFactory4. 解析配置和应用4.1 settings配置4.2 解析 5. jdbc日志5. 1 类图5.2 BaseJdbcLogger5.3 ConnectionLogger5.4 ConnectionLogger的具体应用 1. 适配器模式 适配器使接口不兼容的对象可以相互合…

IDEA常用高效开发工具—screw一键生成数据库文档(仅需三步)

1.配置 引入screw核心... <!-- screw核心 --> <dependency><groupId>cn.smallbun.screw</groupId><artifactId>screw-core</artifactId><version>1.0.3</version> </dependency><!-- HikariCP --> <dependency…

VuePress在生产环境跳转子页报错 Failed to execute ‘appendChild‘ on ‘Node‘

记录一个使用VuePress时遇到的问题 使用VuePress做了一个文档网页&#xff0c;在开发环境的时候一切正常&#xff0c;但是发布到生产环境后&#xff0c;直接跳转二级页面会报错Failed to execute appendChild on Node 比如主页是http://sun/docs/.vuepress/dist/index.html#/…

【C语言项目】三子棋

文章目录 项目思路一、分文件进行创建二、进入游戏前的目录2.1 目录的功能&#xff1a;2.2 目录界面&#xff1a;2.3 选择进入或退出游戏2.4 多次重玩功能 三、画出棋盘3.1 写出棋子3.2 初始化棋盘3.2 画出棋盘的框架3.3 代码实现 四、玩家落子4.1 落子逻辑4.2具体情况分类讨论…

抖斗音直播间评论引流助手,支持直播间喊话+视频评论区喊话=到指定直播间引流精准粉丝【永久脚本+详细教程】

如果你觉得直播间发言手动太麻烦了&#xff0c;或许这个自动工具能帮到你&#xff01; 1.开始运行前&#xff0c;需要手动去打开打开直播间或者视频评论区&#xff0c;再运行脚本。 2.脚本就是模拟人工操作&#xff0c;在相应的APP里进行评论&#xff0c;无突破APP限制功能。…

【Kubernetes运维篇】ingress-nginx实现业务灰度发布详解

文章目录 一、理论&#xff1a;实现灰度发布的几种场景1、场景一&#xff1a;将新版本灰度给部分用户2、场景二&#xff1a;按照比例流程给新版本3、实现灰度发布字段解释 二、实践&#xff1a;1、实验前提环境2、基于Request Header(请求头)进行流量分割3、基于Cookie进行流量…

93.qt qml-自定义Table优化(新增:水平拖拽/缩放自适应/选择使能/自定义委托)

之前我们更新了90.qt qml-Table表格组件(支持表头表尾固定/自定义颜色/自定义操作按钮/排序)_qml 表格_诺谦的博客-CSDN博客 但是一直没出源码,是因为该demo还存在问题,那就是表头表尾固定下,如果是半透明状态下,会看到表头表尾固定后的内容,所以只能重构代码,不能使用重…

Vue3组合式API+TypeScript写法入门

文章目录 前言1.reactive2.ref3.props4.computed5.emit6.watch总结 前言 参考Vue3官网. 本篇以组合式API为例, 但不包含setup语法糖式写法. 原本打算结合class-component, Vue3不推荐就不用了: OverView|Vue Class Component. 而且是不再推荐基于类的组件写法, 推荐单文件组件…

Android App 持续集成性能测试:启动流量

目录 前言&#xff1a; get app UID 获取流量数据 获得启动流量数据 总结 前言&#xff1a; Jenkins 是一种开源的持续集成工具&#xff0c;可以帮助我们更加方便地进行软件开发和测试工作。通过 API 远程管理 Jenkins 可以帮助我们更加方便地进行 Jenkins 的配置和管理工…

react实现路由跳转动画

下载插件 npm i react-transition-group 配置路由 import { createBrowserRouter as ReactRouter,Navigate } from "react-router-dom";import App from ../App.js import Login from "../view/login.js"; import Home from "../home.js"; co…

了解 3DS MAX 3D摄像机跟踪设置:第 4 部分

推荐&#xff1a; NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 1. 项目设置 步骤 1 打开“后效”。 打开后效果 步骤 2 转到合成>新合成以创建新合成。 将“宽度”和“高度”值分别设置为 1280 和 720。将帧速率设置为 25&#xff0c;将持续时间设置为 12 秒。单…

Flask 文件上传,删除上传的文件

目录结构 app.py from flask import Flask, request, render_template, redirect, url_for import osapp Flask(__name__) BASE_DIR os.getcwd() UPLOAD_FOLDER os.path.join(BASE_DIR, testfile)app.route(/) def home():files os.listdir(UPLOAD_FOLDER)return render_t…

欧盟新规,燃油噩梦?2025年起,高速公路每60公里设立一处快充站

根据外媒The Verge报道&#xff0c;欧洲电动汽车用户将获得更多便捷的待遇&#xff0c;同时还能减少有害温室气体排放&#xff0c;这得益于欧盟理事会最新通过的法规。 根据欧盟的法规要求&#xff0c;自2025年起&#xff0c;TEN-T高速公路系统在欧洲将需要每隔60公里设立一座高…

Langchain 和 Chroma 的集成

Langchain 和 Chroma 的集成 1. Chroma2. 基本示例​3. 基本示例(包括保存到磁盘)4. 将 Chroma Client 传递到 Langchain ​5. 基本示例(使用 Docker 容器)6. 更新和删除7. 带分数的相似性搜索​ 1. Chroma Chroma 是一个人工智能原生开源矢量数据库&#xff0c;专注于开发人员…

ES6基础知识六:你是怎么理解ES6中 Promise的?使用场景?

一、介绍 Promise&#xff0c;译为承诺&#xff0c;是异步编程的一种解决方案&#xff0c;比传统的解决方案&#xff08;回调函数&#xff09;更加合理和更加强大 在以往我们如果处理多层异步操作&#xff0c;我们往往会像下面那样编写我们的代码 doSomething(function(resu…

[ 容器 ] Harbor 私有仓库的部署与管理

目录 一、什么是Harbor二、Harbor的特性三、Harbor的构成四、Harbor 部署五、关于 Harbor.cfg 配置文件中有两类参数&#xff1a;所需参数和可选参数六、维护管理Harbor 一、什么是Harbor Harbor 是 VMware 公司开源的企业级 Docker Registry 项目&#xff0c;其目标是帮助用户…