27.<Spring博客系统③(实现用户退出登录接口+发布博客+删除/编辑博客)>
PS:关于打印日志
1.建议在关键节点打印日志。
①请求入口。
②结果响应
2.在可能发生错误的节点打印日志
3.日志不是越多越好。因为打日志也会消耗性能。
日志也可以配置去除重复日志。
一、用户退出功能
判断用户退出。我们只需要在前端将token删掉就可以了。
由于用户退出功能在每一个页面都会用到。因此我们将这个前端代码写在
common.js中。
function logout(){
localStorage.removeItem("user_token");
location.href = "blog_login.html";
}
这样就写好了。
二、发布博客功能
2.1后端代码
Controller
@RequestMapping("/add")
public Boolean publishBlog(String title, String content, HttpServletRequest request){
log.info("publish,接收参数:title{},content{}",title,content);
//1.参数校验
//2.获取当前登录用户
if(!StringUtils.hasLength(title) ||!StringUtils.hasLength(content)){
log.error("title or content为空");
return false;
}
String user_token = request.getHeader(Constant.USER_TOKEN_HEADER);
Integer userId = JWTUtils.getUserIdFromToken(user_token);
if(userId == null || userId<1){
log.error("用户未登录");
return false;
}
BlogInfo blogInfo =new BlogInfo(title,content,userId);
Integer result = blogService.publishBlog(blogInfo);
if(result < 1){
log.error("博客发布失败");
return false;
}
return true;
}
Service
public Integer publishBlog(BlogInfo blogInfo) {
return blogMapper.interBlog(blogInfo);
}
Mapper
@Insert("insert into blog (title, content, user_id) values (#{title},#{content},#{userId})")
Integer interBlog(BlogInfo blogInfo);
测试成功
实现markdown编辑器
editor.md 简单介绍
用户发布博客用到的是一个Markdown编辑器。
editor.md 是一个开源的页面 markdown 编辑器组件.
官网: http://editor.md.ipandao.com/
代码: https://pandao.github.io/editor.md/
使用时引入对应依赖就可以了
"test-editor" 为 markdown编辑器所在的div的id名称path为 editor.md依赖所在的路径
2.2前端代码
function submit() { $.ajax({ type: "post", url: "/blog/add", data:{ title:$("#title").val(), content:$("#content").val(), }, success:function(result){ if(result.code == 200 && result.data == true){ alert("发布成功"); location.href = "/blog_list.html"; }else{ alert("发布失败,标题或正文不能为空!"); } } }); }
发布成功!!!!!
测试成功!
###标题不能正常显示
但是发现,二级标题。一级标题在点击查看全文中还是##。我们如何处理呢
将下面两部分代码
<div class="right"> <div class="content"> <div class="title"></div> <div class="date"></div> <div class="detail"></div> <div class="operating"> <button onclick="window.location.href='blog_update.html'">编辑</button> <button onclick="deleteBlog()">删除</button> </div> </div>
if(result.code == 200 && result.data!=null){ $(".right .content .title").text(blog.title); $(".right .content .date").text(blog.createTime); $(".right .content .detail").text(blog.content);
修改为下面内容就可以了
<div class="right"> <div class="content"> <div class="title"></div> <div class="date"></div> <div class="detail" id="detail" style="background-color: transparent;"></div> <div class="operating"> <button onclick="window.location.href='blog_update.html'">编辑</button> <button onclick="deleteBlog()">删除</button> </div> </div>
success:function(result){ var blog = result.data; if(result.code == 200 && result.data!=null){ $(".right .content .title").text(blog.title); $(".right .content .date").text(blog.createTime); /* $(".right .content .detail").text(blog.content); */ editormd.markdownToHTML("detail", { markdown: blog.content, });
修改之后就会发现。我们再点击查看全文。里面的标题就不是##了 。
会正常显示了
这是博客列表显示的
这是查看全文显示的
除了查看详情。在博客列表中我们也发现还是存在####。
不但如此。我们还希望。在博客列表中只显示一部分博客。而不是将博客全部显示出来。这个又该怎么操作呢?
这个如何修改呢
1.去掉特殊符号
2.对内容长度进行处理
①通过SQL截断
②通过Java截断
在博客列表显示的部分。这里已经更新了。我们通过java截断的方式
public List<BlogInfo> queryBlogList() { List<BlogInfo> blogInfos = blogMapper.selectAllBlog(); for (BlogInfo blog: blogInfos){ String result = blog.getContent(); result = result.replace("#",""); if(result.length() >= 66){ result = result.substring(0,65)+"......"; } blog.setContent(result); } return blogInfos; }
三、实现编译/删除博客(只能删除编辑自己的)
当登录用户和作者是一个人的时候。才应该有编辑和删除按钮。
首先,我们应该处理。在
1.什么时候显示这个操作按钮。
2.实现这个按钮。
3.1实现博客作者和登录用户一样的时候显示编译删除按钮
判断博客作者和登录用户是否一样
实现方式
解耦考虑1、2
1.提供接口,判断作者和登录用户是否一样
2.提供接口,返回登录用户
由于这个项目简单。我们用第三种方法实现。
3.获取博客详情时,顺带返回
首先在博客实体类中加上一个成员变量
private Boolean isLoginUser;
接着在Controller中的/getBlogDetail路由方法中获取登录用户。
给它加上。
HttpServletRequest request
这个参数。
1.获取登录信息。
2.判断登录用户是否为作者。
后端代码实现
@RequestMapping("getBlogDetail")
public BlogInfo queryBlogById(Integer blogId,HttpServletRequest request){
log.info("publish,接收参数:blogId{}",blogId);
BlogInfo blogInfo = blogService.queryBlogById(blogId);
//1.获取登录用户信息
//2.判断用户是否为作者
String user_token = request.getHeader(Constant.USER_TOKEN_HEADER);
Integer userId = JWTUtils.getUserIdFromToken(user_token);
if(userId != null && userId == blogInfo.getUserId()){
blogInfo.setIsLoginUser(true);
}
return blogInfo;
}
前端代码实现
在获取博客详情的前端代码中添加如下代码
//是否实现编辑/删除按钮
if(blog.isLoginUser == true){
var findHtml = "";
findHtml += '<div class="operating">';
findHtml += '<button onclick="window.location.href=\'blog_update.html'+location.search+'\'">编辑</button>';
findHtml += '<button onclick="deleteBlog()">删除</button>';
findHtml += '</div>';
$(".content").append(findHtml);
}
注意Boolean和boolean
如果我们使用的是基本类型的boolean。那么它在
后端代码的写法上和
返回的参数上会与
包装类型Boolean有所区别。
点击编辑显示原文
测试后发现功能已经实现。不过还有一个问题。点击编辑的时候
显示的是固定的内容而不是我们写过的内容。
如何修改呢。我们可以写前端代码
(不正规写法)
将这个代码放在blog_update.html中就可以了
function getBlogInfo() { $.ajax({ type: "get", url: "/blog/getBlogDetail"+location.search, success:function(result){ if(result.code ==200 && result.data != null){ $("#title").val(result.data.title); $("#content").val(result.data.content); $("#title").val(result.data.title); } } }); }
不过当我们刷新的时候,会发现又变回原样了。
这是就是不正规写法会导致的一些错误。那么正规写法是什么样的呢?
正规写法
使用我们Markdown自带的插件的代码填写正文内容
function getBlogInfo() { $.ajax({ type: "get", url: "/blog/getBlogDetail"+location.search, success:function(result){ if(result.code ==200 && result.data != null){ $("#title").val(result.data.title); /* $("#content").val(result.data.content); */ editormd("editor", { width : "100%", height : "550px", path: "blog-editormd/lib/", onload : function(){ this.watch(); this.setMarkdown(result.data.content); } }); } } });
这样就没有任何问题了
3.2更新博客功能实现
后端
/**
* 编辑博客
*/
@RequestMapping("/update")
public Boolean update(Integer blogId,String title,String content){
log.info("updateBlog,接收到的参数title{},content{}",title,content);
if(blogId == null || !StringUtils.hasLength(title) && StringUtils.hasLength(content)){
log.error("Id/标题/内容为空或不合法");
return false;
}
BlogInfo blogInfo = new BlogInfo();
blogInfo.setId(blogId);
blogInfo.setTitle(title);
blogInfo.setContent(content);
Integer result = blogService.updateBlog(blogInfo);
if(result < 1){
log.error("更新失败!");
return false;
}
return true;
}
前端
function submit() {
$.ajax({
type: "post",
url: "/blog/update",
data: {
title: $("#title").val(),
content: $("#content").val(),
blogId : $("#blogId").val()
},
success: function (result) {
if (result.code == 200 && result.data == true) {
alert("更新成功!")
location.href = "blog_list.html";
}
}
});
}
测试:一下页面
更新成功
3.3删除博客功能实现
后端
/**
* 删除博客
*/
@RequestMapping("/delete")
public Boolean delete(Integer blogId){
log.info("删除博客,blogId:{}",blogId);
BlogInfo blogInfo = new BlogInfo();
blogInfo.setId(blogId);
blogInfo.setDeleteFlag(1);
Integer result = blogService.updateBlog(blogInfo);
if(result < 1){
log.error("删除失败!");
return false;
}
return true;
}
前端
function deleteBlog() {
if(confirm("确认删除?")){
$.ajax({
type:"get",
url:"/blog/delete"+location.search,
success:function(result){
if(result.code == 200 && result.data == true){
alert("删除成功!");
location.href = "blog_list.html";
}
}
});
}
}