目录
一、功能和效果
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)效果
点击注销按钮,页面会跳转到博客登录页面。