咱们在这里实现的是后端项目,前端代码就提一提,不全做重点介绍,在开始讲解这个博客系统项目之前,我们先看看这个项目的前端界面:
登录界面:
个人主页:
博客详情页:
写博客页:
注销(回到登录页面):
编写博客系统后端操作
1. 准备工作
- 创建项目
- 引入依赖
- 创建必要目录
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
根据上述可能会用到的四种情况分别设计相应的方法:
- 把一个 Blog 对象插入到数据库中
- 查询 blog 表中所有的博客数据
- 指定一个博客 id 来查询对应的博客
- 指定博客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 即可。