好记性不如烂笔头.
记录一下新手完成过程.
本文主要实现基于servlet的前后端分离博客系统,并部署在Linux云服务器上.
前后端分离的博客系统
什么是servlet?
servlet是Tomcat这个HTTP服务器提供给Java的一组API,来完成构建动态页面这个任务.
什么是动态页面?
指用户不同/时间不同/输入的参数不同,页面内容会发生变化.
什么是前后端分离?
前端只向后端请求数据,而不请求具体的页面,后端也仅仅是返回数据.
这样的设定使前端和后端更加解耦,由浏览器进行具体的页面渲染,减少了服务器的工作量.
一.准备工作
1.环境及软件
- 抓包工具: Fiddler Classic
- 部署: tomcat 8 系列 (对应servlet3.1)
- 环境: jdk1.8
- 后端开发工具: IDEA 2021版 , MySQL
- 前端开发工具: VScode (支持win7的版本最高为1.70.3)
2.博客系统页面设计
①.博客列表页(blog_list.html)
②.博客正文页(blog_detail.html)
③.博客登录页(login.html)
④.博客编辑页(blog_edit.html)
3.创建项目(maven项目)
使用IDEA创建一个Maven项目
菜单 -> 文件 -> 新建项目 -> Maven
项目创建后,得到如图
- src表示源代码所在目录
- main/java表示源代码的根目录,后续创建.java文件就放到这个目录
- main/resources表示项目的一些资源文件所在的目录
- test/java表示测试代码的根目录
4.创建目录(把之前的前端页面拷贝过去)
在main目录下,和java目录并列,创建一个webapp目录.
在webapp目录内部创建一个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>
把之前写的前端页面拷贝到webapp目录中
5.引入依赖(相关jar包)
在pom.xml文件中引入Servlet API依赖的jar包,mysql,jackson.
在中央仓库中搜索"servlet",选择3.1.0版本,复制提供的xml到pom.xml
在中央仓库中搜索"mysql",选择5.1.49版本,复制提供的xml到pom.xml
在中央仓库中搜索"jackson",选择2.14.2版本,复制提供的xml到pom.xml.
pom.xml里面添加如下,
二.设计数据库及其代码编写
1.设计数据库
当前的博客系统中,主要涉及两个实体:博客,用户.
创建两张表来表示博客和用户.
而博客与用户之间的关系:
一对多,一个用户可以写多个博客,一个博客只属于一个用户.
因此创建的两张表如下:
user(userId,username,password)
blog(blogId,title,content,postTime,userId)
2.编写数据库代码
①.编写建库建表语句
编写建库建表语句,保存为db.sql,以备后续部署其他机器时候使用.
此表内容,需要自己手动复制到MySQL里.
②.封装数据库的连接操作(DBUtil.java)
③.创建实体类(和表中的记录对应的类)
实体类中有哪些属性,都是和当前表中的列是密切相关的
user表 -> User类对应 (User的一个对象,就对应表中的一条记录)
blog表 -> Blog类对应 (Blog的一个对象,就对应表中的一条记录)
关于获取时间的get和set方法有一些不一样.
④.封装数据库的增删改查
针对博客表 创建BlogDao.java
针对用户表 创建UserDao.java
依旧需要注意BlogDao.java里的添加新博客里的时间获取.
三.实现博客功能
1.实现获取博客列表功能(博客列表页)
通过数据库读取,数据显示到页面上.
基本思路:
让博客列表页在加载的时候,通过ajax给服务器发一个请求,
服务器查获数据库获取博客列表数据返回给浏览器,
浏览器再根据数据构造页面内容.
实现步骤:
1.约定前后端交互接口
2.开发后端代码(BlogServlet.java 重写doGet方法)
3.开发前端代码(blog_list.html)
①.约定前后端交互接口
在博客列表页,获取博客列表功能下,前端发什么请求,后端返回什么响应.
②.实现后端代码(BlogServlet.java 重写doGet方法)
③.实现前端代码(blog_list.html)
在博客列表页加载过程中,触发ajax请求,访问服务器中的数据,再把拿到的数据构造到页面中.
将之前写死的博客列表页修改.
每实现一个功能,及时查看一下是否有完成
抓包
2.博客详情页
基本思路:
点击"查看全文"按钮,就能跳转到博客详情页中,跳转过去之后,
在博客详情页中发起一个ajax,从服务器获取到当前的博客具体内容,再显示出来.
实现步骤:
1.约定前后端交互接口
2.实现后端代码(BlogServlet.java 重写doGet方法)
3.实现前端代码(blog_detail.html)
①.约定前后端交互接口
Ⅰ关于请求
此时路径和博客列表页是同一个.
之前的博客列表,请求里没有query string,而现在的博客详情页是带有query string.
因此就可以判断query string,存在就返回博客的详情页,不存在就返回博客列表.
Ⅱ关于响应
此时的content不再像博客列表页一样截断了,它是完整的正文内容.
②.实现后端代码(BlogServlet.java 重写doGet方法)
③.实现前端代码(blog_detail.html)
将之前写死的内容修改.
3.登录页
基本思路:
在此处输入用户名和密码,点击登录,就会触发一个http请求,
服务器验证用户名和密码,就可以根据结果判定是否登录成功,
如果成功就跳转到博客列表页.
实现步骤:
1.约定前后端交互接口
2.修改后端代码(LoginServlet.java 重写doPost方法)
3.修改前端代码(login.html)
把页面里加上form表单,使点击登录操作能够触发请求
①.约定前后端交互接口
Ⅰ关于响应
得是form表单,响应是302,才能够进行页面跳转(form表单本身就会触发页面跳转)
如果是ajax请求,响应也是302,但是无法跳转(ajax本身不会触发页面跳转)
②.修改后端代码(LoginServlet.java 重写doPost方法)
③.实现前端代码(login.html)
把页面加上form表单,使点击登录操作能够触发请求.
4.实现页面强制要求登陆
当用户访问博客列表页/详情页/编辑页,要求用户必须是已经登陆的状态,
如果用户还没登陆,就强制跳转到登录页面.
基本思路:
在页面加载的时候,专门发起一个新的ajax(一个页面可以发起多个ajax请求),
以博客列表页为例,会先发一个请求获取博客列表页,再发个ajax获取用户的登录状态,
如果未登录,页面就会跳转到登录页.
实现步骤:
1.约定前后端交互接口
2.实现后端代码(LoginServlet.java 重写doGet方法)
3.实现前端代码(好几个页面里)
①.约定前后端交互接口
Ⅰ关于响应
响应就把当前登录的用户信息返回回来,
如果未登录,就返回一个userId为0的user对象.
②.实现后端代码(LoginServlet.java 重写doGet方法)
③.实现前端代码(blog_list.html / blog_edit.html / blog_detail.html)
5.显示用户信息
1.如果是博客列表页,此处显示登录用户信息.
2.如果是博客详情页,此时显示的是该文章的作者.
实现步骤:
1.约定前后端交互接口
2.修改后端代码(AuthorServlet.java 重写doGet方法)
3.修改前端代码
①.约定前后端交互接口
Ⅰ.关于博客列表页
后端代码已经有了,只需稍微调前端代码,把得到的用户信息显示出来即可.
Ⅱ.关于博客详情页
重新来实现
②.实现后端代码(AuthorServlet.java 重写doGet方法)
博客详情页的显示用户信息功能实现代码
③.实现前端代码
博客列表页(blog_list.html),在之前的代码加上显示用户信息.
博客详情页(blog_detail.html , getAuthor()函数)
6.退出登录状态(注销)
判定登录状态:
1.看是否能查到Http Session对象
2.看session对象里有没有user
实现退出登录:销毁HttpSession,或者销毁user
但是getSession能够创建获取会话,没有删除会话的方法,直接删除不好删,
可以通过设置会话的过期时间来达到类似的效果.
因此更好的办法是将user对象销毁,使用removeAttribute就删了.
之前的逻辑中,httpsession 和里面的user一定是一荣俱荣,一损俱损.
但是引入注销逻辑后,就会出现有httpsession无user的情况,
因此之前的判定登陆状态,也要判定user.
实现步骤:
1.约定前后端交互接口
2.修改后端代码(LogoutServlet.java 重写doGet方法)
3.修改前端代码
①.约定前后端交互接口
②.实现后端代码(logoutServlet.java 重写doGet方法)
③.实现前端代码
此时的请求是通过a标签触发的,不再是ajax了.
7.发布博客
实现步骤:
1.约定前后端交互接口
2.实现后端代码(BlogServlet.java doPost)
3.实现前端代码
①.约定前后端交互接口
使用form表单
同时让form里面能够感知到博客的内容.
一篇博客:
blogId 自增主键,数据库自己生成
title
content
postTime 当前时刻
userId 作者信息,看提交的用户是谁,从会话中就能够拿到
因此只需要知道title和content
②.实现后端代码(BlogServlet.java 重写doPost方法)
③.实现前端代码
其中
这是editor.md文档要求的写法.
editor.md 对于form表单也是支持的,就是可以在form里放一个隐藏的textarea.
editor.md 就会自动把用户输入的markdown内容贴写道textarea里,
后续点击submit就能自动提交.
四.部署Linux上
1.Linux环境搭建
在腾讯云或者阿里云,等服务器厂商处直接购买一个云服务器.
使用云服务器不仅环境搭建简单,避免折腾,部署在云服务器上的项目可以直接被外网访问到,
让自己写的程序真的给大家使用到.
①.进入官网购买云服务器
操作系统选择CentOS 7.6 64位
②.查看公网IP地址,重置密码
购买完成后,可以在控制台找到自己买的服务器,点进去可以看见服务器的公网ip地址.
首次使用需要设置密码
③.使用单独的终端工具进行登录
关于XShell下的复制黏贴
复制: ctrl + insert
黏贴 : shift + insert
安装好之后,打开界面如图
点击文件选择新建
看到命令提示符就相当于连接成功了
④.安装对应的软件程序
Ⅰ.jdk
直接使用包管理器进行安装(基于yum安装)
安装的这个过程需要联网(云服务器本身就是联网的)
语句:
找到要安装的包名
yum list | grep jdk
进行安装
yum install java-1.8.0-openjdk-devel.x86_64
安装后,查看是否安装成功,显示如下就是安装成功了.
语句:
javac
Ⅱ. tomcat 8 系列
手动安装tomcat,从官网上下载的.zip压缩包,上传到Linux上,就可以直接使用了.
将在官网下载的.zip压缩包拖拽到Linux里.
如果拖拽失败,可能需要先输入:yum install lrzsz
下载Tomcat压缩包,Tomcat官网链接
拖拽进Linux里.
再解压压缩包,如果解压失败,可能需要先输入:yum install unzip
语句:
unzip apache-tomcat-8.5.88.zip
进入tomcat的bin目录,给所有的.sh文件赋予可执行权限
语句:
cd apache-tomcat-8.5.88/
ll
cd bin/
ll
chmod +x *.sh
ll
.sh文件都变成绿色,就是可执行文件了.
Ⅲ.mysql
关于mysql
yum上的是MariaDB,从实用角度上MariaDB和MySQL之间是兼容的.
安装语句:
安装mariadb服务
yum install -y mariadb-server
安装mariadb命令行客户端
yum install -y mariadb
安装 mariadb C library
yum install -y mariadb-libs
安装 mariadb 开发包
yum install -y mariadb-devel
启动服务
systemctl start mariadb
设置服务开启自启动
systemctl enable mariadb
查看服务状态
systemctl status mariadb
使用命令行客户端尝试连接
mysql -uroot
按照上述语句逐条输入即可,最后连接成功.
关于数据库中中文显示乱码问题.解决方法如下,依旧逐条输入语句.
语句:
查看数据库默认编码格式
show variables like 'chara%';
退出数据库(或者按ctrl + d)
quit;
修改配置文件/etc/my.cnf
vim /etc/my.cnf
重启mysql服务
systemctl restart mariadb
mysql -uroot -p
再次查看编码格式
show variables like 'chara%';
在打开的my.cnf文件中,添加以下标红语句.
如果没有[client],[mysql],[mysqld]其中任何字段,就自己添加上去
关于vim的一些操作
vim是文本编辑器
创建文件/打开文件 : vim [文件名]
进入插入模式:
vim打开文件后是普通模式,需要进入插入模式才能进行文本编辑.
使用i键可以进入插入模式.
保存:
在插入模式下不能保存文件,需要先回到普通模式,按下esc回到普通模式.
在普通模式下输入:w再按下回车即可保存文件.
退出:
在插入模式不能退出,需要先回到普通模式.
在普通模式下输入:q再按下回车即可退出.
也可以直接使用:wq同时执行保存和退出.
语句:
[mysql]
default-character-set=utf8
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
symbolic-links=0
character-set-server=utf8
default-storage-engine=innodb
[client]
socket = /var/lib/mysql/mysql.sock
default-character-set=utf8
文件修改保存后,再重启mysql服务,查看编码格式.
正常显示中文了
2.部署Web项目到Linux
①.在云服务器的mysql进行建库建表
把之前写好的db.sql里面的内容复制黏贴到云服务器mysql客户端里,直接运行即可.
建库建表完成,如图所示.
②.微调代码
本地的数据库,端口号,用户名,密码和云服务器的数据库,可能是不同的,所以需要微调.
DBUtil.java文件里将密码改掉,如果没有刻意设置密码,此处密码为空.
可能还需要改端口号,查看mysql使用的端口号.
语句:
netstat -anp | grep mysql
③使用waven打成war包
在pom.xml文件里,添加语句
使用maven打成war包.
点击右侧的Maven,选择Lifecycle目录下的package,右键选择Run Maven Build.
生成war包,在target目录下.
④.把war包拷贝到云服务器里
把war包拷贝到云服务器的webapps目录.
进入tomcat的webapps目录下
语句:
cd apache-tomcat-8.5.88/
cd webapps/
ll
注意: cd apache-tomcat-8.5.88/ 这里的apache-tomcat-8.5.88/是跟自己下载的tomcat压缩包文件名对应的
将war包拖拽进去
切回目录,启动tomcat服务器.
语句:
cd ..
cd bin/
sh startup.sh
通过netstat来验证tomcat是否启动成功.
语句:
netstat -anp | grep 8080
另外,云服务器厂商为了保证机器的安全,引入安全机制,默认情况下只有机器的22端口是可以对外访问的,要想让其他端口被外面访问,就需要手动放开.
因此想要正常访问网页,还需开放8080端口,登陆腾讯云,点击近购买的云服务器里,选择防火墙选项,再选择添加规则.
把8080端口放开即可,点击确定之后,生效可能需要几分钟左右.
⑤.验证
网页验证是否部署成功
博客登录页
博客列表页
博客详情页
博客编辑页
最后
我的项目源代码地址:github-BlogSystem