发布时间:2022-08-19 14:11
目录
展示
1.创建项目
2. 数据库设计
2.1 表设计
2.2 封装数据库操作代码
2.2.1 创建 DBUtil
2.2.2 创建实体类
2.2.3 封装数据库增删改查
3.实现博客列表
3.1 约定前后端交互接口
3.2 实现服务器代码
3.3 实现客户端代码
4. 实现博客详情
4.1 约定前后端交互接口
4.2 实现服务器代码
4.3 实现客户端代码
5. 实现登陆
5.1 约定前后端交互接口
5.2 实现服务器代码
5.3 实现客户端代码
5.4 实现强制要求登陆和写博客
编辑
6. 实现显示用户信息
6.1 约定前后端交互接口
6.2 实现服务器代码
7. 实现注销登陆
7.1 约定前后端交互接口
7.2 实现服务器代码
8. 实现删除博客
8.1 约定前后端交互接口
8.2 实现服务器代码
8.3 实现客户端代码
博客项目
1)创建 maven 项目,并添加webapp目录
2)配置web.xml
Archetype Created Web Application
3)配置 pom.xm
javax.servlet
javax.servlet-api
3.1.0
provided
com.fasterxml.jackson.core
jackson-databind
2.12.6.1
mysql
mysql-connector-java
5.1.47
4)引入前端代码
将前端的代码复制到 webapp 目录下
需要设计两张表,文章表和用户表
文章表用来存储博客文,用户表用于存储登录用户
--创建库
create database if not exists blog_web;
use blog_web;
drop table if exists blog;
--建博客表
create table blog (
blogId int primary key auto_increment,
title varchar(1024),
content mediumtext,--内容,存放大量数据
userId int,
postTime datetime --时间
);
--插入数据
insert into blog values(null, '博客一', '认真学 C', 1, now());
insert into blog values(null, '博客二', '认真学 GO', 1, now());
--用户表
drop table if exists user;
create table user (
userId int primary key auto_increment,--自增主键
username varchar(128) unique, --用户唯一
password varchar(128)
);
--用户
insert into user values(null, 'FlyUpward', '');--密码自己设
insert into user values(null, 'Fly', '');--密码自己设
将表复制到 mysql 中进行建表
先在Java目录下创建一个model包,用于存放数据库后端类
这个类用于和数据库建立连接
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 final String URL = "jdbc:mysql://127.0.0.1:3306/bolg_web?characterEncoding=utf8&useSSL=false";
private static final String USERNAME = "root";
private static final String PASSWORD = "";//自己数据库的密码
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(URL);
((MysqlDataSource)dataSource).setUser(USERNAME);
((MysqlDataSource)dataSource).setPassword(PASSWORD);
}
}
}
return dataSource;
}
private static Connection getConnection() throws SQLException {
return getDataSource().getConnection();
}
public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet) {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
实体类用于表示数据库的记录
1)Blog.java
每个 model.Blog 对象, 对应 blog 表里的一条记录
package model;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
public class Blog {
private int blogId;
private String title;
private String content;
private int UserId;
private Timestamp postTime;
public int getBlogId() {
return blogId;
}
public void setBlogId(int blogId) {
this.blogId = blogId;
}
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 int getUserId() {
return UserId;
}
public void setUserId(int userId) {
UserId = userId;
}
/*public Timestamp getPostTime() {
return postTime;
}*/
// 把这里的 getter 方法给改了, 不是返回一个时间戳对象, 而是返回一个 String (格式化好的时间)
public String getPostTime() {
// 使用 SimpleDateFormat 来完成时间戳到格式化日期时间的转换.
// 这个转换过程, 需要在构造方法中指定要转换的格式, 然后调用 format 来进行转换
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return simpleDateFormat.format(postTime);
}
public void setPostTime(Timestamp postTime) {
this.postTime = postTime;
}
}
2) User.java
对于用户表里的每一条记录
package model;
public class User {
private int userId = 0;
private String username = "";
private String password = "";
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
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;
}
}
解 DAODAO 全称为 "data access object",主要的功能就是对于某个数据库表进行增删改查.一般每张数据库表会对应一个 DAO 类. 这是一种给类命名的习惯做法, 并不是强制要求
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 BlogDao {
//1.插入博客
public void insert(Blog blog) {
Connection connection = null;
PreparedStatement statement = null;
try {
//1)和数据库建立连接
connection = DBUtil.getConnection();
//2)构造sql语句
String sql = "insert into blog values(null,?,?,?,now())";
statement = connection.prepareStatement(sql);
statement.setString(1,blog.getTitle());
statement.setString(2,blog.getContent());
statement.setInt(3,blog.getUserId());
//30执行SQL
statement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.close(connection,statement,null);
}
}
// 2. 能够获取到博客表中的所有博客的信息 (用于在博客列表页, 此处每篇博客不一定会获取到完整的正文)
public List selectAll() {
List blogs = new ArrayList<>();
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
connection = DBUtil. getConnection();
String sql = "select * from blog order by postTime desc";
statement = connection.prepareStatement(sql);
resultSet = statement.executeQuery();//查询
while (resultSet.next()) {
Blog blog = new Blog();
blog.setBlogId(resultSet.getInt("blogId"));
blog.setTitle(resultSet.getString("title"));
// 这里需要针对内容进行截断(太长了, 就去掉后面)
String content = resultSet.getString("content");
// 这个数字具体写多少, 都可以灵活应对!!
if (content.length() > 10) {
content = content.substring(0,10) + "......";
}
blog.setContent(content);
blog.setUserId(resultSet.getShort("userId"));
blog.setPostTime(resultSet.getTimestamp("postTime"));
blogs.add(blog);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.close(connection, statement, resultSet);
}
return blogs;
}
// 3. 能够根据博客 id 获取到指定的博客内容 (用于在博客详情页)
public Blog selectOne(int blogId) {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
connection = DBUtil.getConnection();
String sql = "select * from blog where blogId = ?";
statement = connection.prepareStatement(sql);
statement.setInt(1,blogId);
resultSet = statement.executeQuery();
// 此处我们是使用 主键 来作为查询条件的. 查询结果, 要么是 1 , 要么是 0.
if (resultSet.next()) {
Blog blog = new Blog();
blog.setBlogId(resultSet.getInt("blogId"));
blog.setTitle(resultSet.getString("title"));
blog.setContent(resultSet.getString("content"));
blog.setUserId(resultSet.getShort("userId"));
blog.setPostTime(resultSet.getTimestamp("postTime"));
return blog;
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
DBUtil.close(connection, statement, resultSet);
}
return null;
}
// 4. 从博客表中, 根据博客 id 删除博客.
public void delete(int blogId) {
Connection connection = null;
PreparedStatement statement = null;
try {
connection = DBUtil.getConnection();
String sql = "delete from blog where blogId = ?";
statement = connection.prepareStatement(sql);
statement.setInt(1,blogId);
statement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.close(connection, statement, null);
}
}
}
2)创建 UserDao 类
package model;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
//提供了针对用户表的基本操作
public class UserDao {
public void insert(User user){
Connection connection = null;
PreparedStatement statement = null;
try {
connection = DBUtil.getConnection();
String sql = "insert into user values(null,?,?)";
statement = connection.prepareStatement(sql);
statement.setString(1, user.getUsername());
statement.setString(2, user.getPassword());
statement.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
DBUtil.close(connection,statement,null);
}
}
//主要实现
// 1. 根据用户名来查找用户信息
//这个会在登录逻辑中使用
public User selectByName(String username) {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
connection = DBUtil.getConnection();
String sql = "select * from user where username = ?";
statement = connection.prepareStatement(sql);
statement.setString(1, username);
resultSet = statement.executeQuery();
// 此处 username 使用 unique 约束, 要么能查到一个, 要么一个都查不到.
if (resultSet.next()) {
User user = new User();
user.setUserId(resultSet.getInt("userId"));
user.setUsername(resultSet.getString("username"));
user.setPassword(resultSet.getString("password"));
return user;
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtil.close(connection, statement, resultSet);
}
return null;
}
// 2. 根据用户 id 来找用户信息.
// 博客详情页, 就可以根据用户 id 来查询作者的名字, 把作者名字显示出来.
public User selectById(int userId) {
Connection connection = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
connection = DBUtil.getConnection();
String sql = "select * from user where userId = ?";
statement = connection.prepareStatement(sql);
statement.setInt(1, userId);
resultSet = statement.executeQuery();
// 此处 username 使用 unique 约束, 要么能查到一个, 要么一个都查不到.
if (resultSet.next()) {
User user = new User();
user.setUserId(resultSet.getInt("userId"));
user.setUsername(resultSet.getString("username"));
user.setPassword(resultSet.getString("password"));
return user;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
DBUtil.close(connection, statement, resultSet);
}
return null;
}
}
[ 请求 ]GET / blog[ 响应 ][{blogId : 1 ,title : " 第一篇博客 " ,content : " 博客摘要 " ,userId : 1 ,postTime : "2022-07-06 12:00:00"},{blogId : 2 ,title : " 第二篇博客 " ,content : " 博客摘要 " ,userId : 1 ,postTime : "2022-07-06 12:10:00"},...]
1)先获取数据库列表并转换成json 格式,看是否交互成功
@WebServlet("/blog")
public class BlogServlet extends HttpServlet {
private ObjectMapper objectMapper = new ObjectMapper();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//从数据库中查询到博客列表,转成json 格式
//获取博客列表
BlogDao blogDao = new BlogDao();
List blogs = blogDao.selectAll();
//转换
String respJson = objectMapper.writeValueAsString(blogs);
resp.setContentType("application/json;charset=utf8");
resp.getWriter().write(respJson);
}
}
2) 通过postman 验证可知,交互成功
[ 请求 ]GET / blog ? blogId = 1[ 响应 ]{blogId : 1 ,title : " 第一篇博客 " ,content : " 博客正文 " ,userId : 1 ,postTime : "2022-07-06 12:00:00"},
根据 blogId 参数是否存在, 判定当前是获取博客列表还是获取博客详情
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("application/json;charset=utf8");
BlogDao blogDao = new BlogDao();
// 先尝试获取到 req 中的 blogId 参数. 如果该参数存在, 说明是要请求博客详情
// 如果该参数不存在, 说明是要请求博客的列表.
String param = req.getParameter("blogId");
if (param == null) {
//不存在参数,获取列表
List blogs = blogDao.selectAll();
//把blog 对象转成json 格式
String respJson = objectMapper.writeValueAsString(blogs);
resp.getWriter().write(respJson);
} else {
// 存在参数, 获取博客详情
int blogId = Integer.parseInt(param);
Blog blog = blogDao.selectOne(blogId);
String respJson = objectMapper.writeValueAsString(blog);
resp.getWriter().write(respJson);
}
}
1) 引入 editor.md
[ 请求 ]POST /loginContent-Type: application/x-www-form-urlencodedusername=test&password=“ ”[ 响应 ]HTTP/1.1 302Location: blog_list.html
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
private ObjectMapper objectMapper = new ObjectMapper();
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf8");
resp.setCharacterEncoding("utf8");
// 1. 获取到请求中的参数
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println("username=" + username + ", password=" + password);
if (username == null || "".equals(username) || password == null || "".equals(password)) {
// 请求的内容缺失, 肯定是登录失败!!
resp.setContentType("text/html; charset=utf8");
resp.getWriter().write("当前的用户名或密码为空,请重新输入!");
return;
}
// 2. 和数据库中的内容进行比较
UserDao userDao = new UserDao();
User user = userDao.selectByName(username);
if (user == null || !user.getPassword().equals(password)) {
// 用户没有查到或者密码不匹配, 也是登录失败!
resp.setContentType("text/html; charset=utf8");
resp.getWriter().write("用户名或密码错误,请重新输入!");
return;
}
// 3. 如果比较通过, 就创建会话.
HttpSession session = req.getSession(true);
// 把刚才的用户信息, 存储到会话中.
session.setAttribute("user", user);
// 4. 返回一个重定向报文, 跳转到博客列表页.
resp.sendRedirect("blog_list.html");
}
// 这个方法用来让前端检测当前的登录状态.
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("application/json;charset=utf8");
HttpSession session = req.getSession(false);
if (session == null) {
// 检测下会话是否存在, 不存在说明未登录!
User user = new User();
resp.getWriter().write(objectMapper.writeValueAsString(user));
return;
}
User user = (User) session.getAttribute("user");
if (user == null) {
// 虽然有会话, 但是会话里没有 user 对象, 也视为未登录.
user = new User();
resp.getWriter().write(objectMapper.writeValueAsString(user));
return;
}
// 已经登录的状态!!
// 注意, 此处不要把密码给返回到前端
user.setPassword("");
resp.getWriter().write(objectMapper.writeValueAsString(user));
}
}
修改blog_login.html
给输入框套上一层 form 标签 . action 为 login, method 为 POST给 input 加上 name 属性。提交按钮改成
登录
用户名
密码
修改blog_login.css
将 .row button{ } 和 .row button:active{ } 修改成下面的样式
.row #submit {
width: 300px;
height: 50px;
border-radius: 10px;
color: white;
background-color: rgb(0, 128, 0);
border: none;
outline: none;
margin-top: 50px;
}
.row #submit:active {
background-color: #666;
}
当用户访问 博客列表页 和 博客详情页 时, 如果用户当前尚未登陆, 就自动跳转到登陆页面。
1)修改 BlogServlet
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession(false);
if (session == null) {
// 当前用户未登录, 不能提交博客!
resp.setContentType("text/html;charset=utf8");
resp.getWriter().write("当前用户未登录,不能提交博客");
return;
}
User user = (User) session.getAttribute("user");
if (user == null) {
// 当前用户未登录, 不能提交博客!
resp.setContentType("text/html;charset=utf8");
resp.getWriter().write("当前用户未登录,不能提交博客");
return;
}
// 一定要先指定好请求按照哪种编码来解析
req.setCharacterEncoding("utf8");
// 先从请求中, 取出参数(博客的标题和正文)
String title = req.getParameter("title");
String content = req.getParameter("content");
if (title == null || "".equals(title) || content == null || "".equals(content)) {
// 直接告诉客户端, 请求参数不对
resp.setContentType("text/html;charset=utf8");
resp.getWriter().write("提交博客失败!缺少必要参数!");
return;
}
// 构造 Blog 对象, 把当前的信息填进去, 并插入数据库中
// 此处要给 Blog 设置的属性, 主要是 title, content, userId (作者信息)
// postTime 和 blogId 都不需要手动指定, 都是插入数据库的时候自动生成的.
Blog blog = new Blog();
blog.setTitle(title); //标题
blog.setContent(content); //摘要
// 作者 id 就是当前提交这个博客的用户的身份信息
blog.setUserId(user.getUserId());
BlogDao blogDao = new BlogDao();
blogDao.insert(blog);
// 重定向到, 博客列表页!
resp.sendRedirect("blog_list.html");
}
2)修改 blog_list.html
common.js
// 这个文件里放一些页面公共的代码
// 加上一个逻辑, 通过 GET /login 这个接口来获取下当前的登录状态~
function getUserInfo(pageName) {
$.ajax({
type: 'get',
url: 'login',
success: function(body) {
// 判定此处的 body 是不是一个有效的 user 对象(userId 是否非 0)
if (body.userId && body.userId > 0) {
// 登录成功!
// 不做处理!
console.log("当前用户登录成功! 用户名: " + body.username);
// 根据当前用户登录的情况, 把当前用户名设置到界面上
if (pageName == 'blog_list.html') {
changeUserName(body.username);
}
} else {
// 登录失败!
// 让前端页面, 跳转到 login.html
alert("当前您尚未登录! 请登录后再访问博客列表!");
location.assign('blog_login.html');
}
},
error: function() {
alert("当前您尚未登录! 请登录后再访问博客列表!");
location.assign('blog_login.html');
}
});
}
function changeUserName(username) {
let h3 = document.querySelector('.card>h3');
h3.innerHTML = username;
}
3)修改 blog_detail.html
在文件中增加以下代码
// 加上一个逻辑, 通过 GET /login 这个接口来获取下当前的登录状态
function getUserInfo(pageName) {
$.ajax({
type: 'get',
url: 'login',
success: function(body) {
// 判定此处的 body 是不是一个有效的 user 对象(userId 是否非 0)
if (body.userId && body.userId > 0) {
// 登录成功!
// 不做处理!
console.log("登录成功!用户名:“+ body.username");
// 在 getUserInfo 的回调函数中, 来调用获取作者信息
getAuthorInfo(body);
} else {
// 登录失败!
// 让前端页面, 跳转到 login.html
alert("当前您未登录,请登录后再访问博客列表!");
location.assign('blog_login.html');
}
},
error: function() {
alert("当前您未登录,请登录后再访问博客列表!");
location.assign('blog_login.html');
}
});
}
// 判定用户的登录状态
getUserInfo("blog_detail.html");
4)修改 blog_edit.html
5)修改blog_edit.css
将.blog-edit-container .title button{ }
.blog-edit-container .title button:active{ }
修改成下面的样式
.blog-edit-container .title #submit {
width: 100px;
height: 40px;
border-radius: 10px;
color: white;
background-color: orange;
border: none;
outline: none;
font-size: 18px;
}
.blog-edit-container .title #submit:active {
background-color: #666;
}
验证
[ 请求 ]GET /authorInfo[ 响应 ]{userId: 1,username: Fly Upward}
在博客详情页, 获取当前文章作者的用户信息
[ 请求 ]GET /user?blogId=1[ 响应 ]{userId: 1,username: Fly Upward}
建一个AuthorServlet
@WebServlet("/authorInfo")
public class AuthorServlet extends HttpServlet {
private ObjectMapper objectMapper = new ObjectMapper();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("application/json; charset=utf8");
// 通过这个方法, 来获取到指定的博客的作者信息.
String param = req.getParameter("blogId");
if (param == null || "".equals(param)) {
// 参数缺少了.
resp.getWriter().write("{ \"ok\": false, \"reason\": \"参数缺失!\" }");
return;
}
// 根据当前 blogId 在数据库中进行查找, 找到对应的 Blog 对象, 再进一步的根据 blog 对象, 找到作者信息.
BlogDao blogDao = new BlogDao();
Blog blog = blogDao.selectOne(Integer.parseInt(param));
if (blog == null) {
resp.getWriter().write("{ \"ok\": false, \"reason\": \"要查询的博客不存在!\" }");
return;
}
// 根据 blog 对象, 查询到用户对象
UserDao userDao = new UserDao();
User author = userDao.selectById(blog.getUserId());
if (author == null) {
resp.getWriter().write("{ \"ok\": false, \"reason\": \"要查询的用户不存在!\" }");
return;
}
// 把 author 返回到浏览器这边
// 注意要把密码去掉
author.setPassword("");
resp.getWriter().write(objectMapper.writeValueAsString(author));
}
}
为了避免麻烦和混淆,服务器代码在上面的blog_list.html 和 blog_detail.html 已经实现好了。
[ 请求 ]GET /logout[ 响应 ]HTTP/1.1 302Location: login.html
创建 LogoutServlet
@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 先找到当前用户的会话,
HttpSession session = req.getSession(false);
if (session == null) {
// 用户没有登录!! 谈不上注销!
resp.getWriter().write("当前用户尚未登录! 无法注销!");
return;
}
// 然后把这个用户的会话中的信息给删掉就行了!!
session.removeAttribute("user");
resp.sendRedirect("blog_login.html");
}
}
[ 请求 ]GET / user ? blogId = 1[ 响应 ]{userId : 1 ,username : test ,isYourBlog : 1 , // 1 表示当前博客就是登陆者的博客 . 0 表示当前博客不是登陆者的博客}
DELETE /blog?blogId=1[ 响应 ]HTTP/1.1 200
@WebServlet("/blogDelete")
public class BlogDeleteServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 检查当前用户是否登录
HttpSession session = req.getSession(false);
if (session == null) {
resp.setContentType("text/html; charset=utf8");
resp.getWriter().write("当前尚未登录, 不能删除!");
return;
}
User user = (User) session.getAttribute("user");
if (user == null) {
resp.setContentType("text/html; charset=utf8");
resp.getWriter().write("当前尚未登录, 不能删除!");
return;
}
// 2. 获取到参数中的 blogId
String blogId = req.getParameter("blogId");
if (blogId == null || "".equals(blogId)) {
resp.setContentType("text/html; charset=utf8");
resp.getWriter().write("当前 blogId 参数不对!");
return;
}
// 3. 获取要删除的博客信息.
BlogDao blogDao = new BlogDao();
Blog blog = blogDao.selectOne(Integer.parseInt(blogId));
if (blog == null) {
resp.setContentType("text/html; charset=utf8");
resp.getWriter().write("当前要删除的博客不存在!");
return;
}
// 4. 再次校验, 当前的用户是否就是博客的作者
if (user.getUserId() != blog.getUserId()) {
// 这一点在前端这里其实也处理过~~ 但是此处还是再校验一次, 不是坏事!!!
resp.setContentType("text/html; charset=utf8");
resp.getWriter().write("当前登录的用户不是作者, 没有权限删除!");
return;
}
// 5. 确认无误, 开始删除
blogDao.delete(Integer.parseInt(blogId));
// 6. 重定向到博客列表页
resp.sendRedirect("blog_list.html");
}
}
修改blog_detail.html
// 从服务器获取一下当前博客的作者信息, 并显示到界面上.
// 参数 user 就是刚才从服务器拿到的当前登录用户的信息
function getAuthorInfo(user) {
$.ajax({
type: 'get',
url: 'authorInfo' + location.search,
success: function(body) {
// 此处的 body, 就是服务器返回的 User 对象, 是文章的作者信息
if (body.username) {
// 如果响应中的 username 存在, 就把这个值设置到页面上.
changeUserName(body.username);
if (body.username == user.username) {
// 作者和登录的用户是一个人, 则显示 "删除按钮"
let navDiv = document.querySelector('.nav');
let a = document.createElement('a');
a.innerHTML = '删除';
// 期望点击删除, 构造一个形如 blogDelete?blogId=6 这样的请求
a.href = 'blogDelete' + location.search;
navDiv.appendChild(a);
}
} else {
console.log('获取作者信息失败!' + body.reason);
}
}
});
AutoJs4.1.0实战教程---js文件打包发布成APK文件
c语言字符串函数strcat strcpy strlen strcmp的用法及原型
罗永浩宣布退网创业;谷歌研究员“走火入魔”事件曝光:认为AI已具备人格,被罚带薪休假;Wasmer 2.3 发布|极客头条
【论文阅读】Two-Stream Convolutional Networks for Action Recognition in Videos
深度网络设计技巧(五)之VAN:Visual Attention Network#超越Swin的纯CNN#
React + Typescript领域初学者的常见问题和技巧(最新)