参考牛客网高级项目教程
尚硅谷SpringSecurity教程笔记
社区 Spring Security 从入门到进阶系列教程 Thymeleaf+Spring Security
功能需求
一、置顶、加精、删除帖子功能的实现
1. dao层处理数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VGj3MxIS-1649167308072)(C:\Users\ls2690069470\AppData\Roaming\Typora\typora-user-images\image-20220405182107015.png)]
接口定义
sal语句定义
<!
<update id="updatePostType">
update discuss_post set type =
</update>
<!
<update id="updatePostStatus">
update discuss_post set status =
</update>
2. service层业务处理
public int updatePostType(int id, int type) {
return discussPostMapper.updatePostType(id, type);
}
public int updatePostStatus(int id, int status) {
return discussPostMapper.updatePostStatus(id, status);
}
3. Controller层处理按钮事件异步请求
- 采用异步请求
- 注意:更改帖子后,要将帖子信息同步到ES服务器中,
- 故,要增加发帖事件-进kafka消息队列中
- 增加kafak删除帖子的消费事件
异步请求及kafka发送消息
private static final int POST_TYPE_TOP = 1;
private static final int POST_STATUS_WONDERFUL = 1;
private static final int POST_STATUS_DELETE = 2;
@RequestMapping(value = "/top", method = RequestMethod.POST)
@ResponseBody
public String setTop(int id) {
discussPostService.updatePostType(id, POST_TYPE_TOP);
Event event = new Event()
.setTopic(TOPIC_PUBLISH)
.setEntityId(id);
eventProducer.sendEvent(event);
return CommunityUtil.getJSONString(0);
}
@RequestMapping(value = "/wonderful", method = RequestMethod.POST)
@ResponseBody
public String setWonderful(int id) {
discussPostService.updatePostStatus(id, POST_STATUS_WONDERFUL);
Event event = new Event()
.setTopic(TOPIC_PUBLISH)
.setEntityId(id);
eventProducer.sendEvent(event);
return CommunityUtil.getJSONString(0);
}
@RequestMapping(value = "/delete", method = RequestMethod.POST)
@ResponseBody
public String deletePost(int id) {
discussPostService.updatePostStatus(id, POST_STATUS_DELETE);
Event event = new Event()
.setTopic(TOPIC_DELETE)
.setEntityId(id);
eventProducer.sendEvent(event);
return CommunityUtil.getJSONString(0);
}
删除帖子-消费消息
@KafkaListener(topics = TOPIC_DELETE)
public void handleDeleteMessage(ConsumerRecord record) {
if (record == null || record.value() == null) {
logger.error("消息的内容为空!");
return;
}
Event event = JSONObject.parseObject(record.value().toString(), Event.class);
if(event == null) {
logger.error("消息的格式错了!");
return;
}
DiscussPost discussPost = discussPostService.selectPostById(event.getEntityId());
elasticSearchService.deletePost(discussPost);
}
4. 模板页面和js文件处理
帖子详情页面按钮处理
- 增加隐藏标签,传入帖子id,请求处理中需要这个参数
th:disabled - 按钮不起作用
- 当按钮已经操作之后,防止重复操作,设置按钮不起作用
<div class="float-right">
<input type="hidden" id="postId" th:value="${post.id}">
<button type="button" class="btn btn-danger btn-sm" id="topBtn"
th:disabled="${post.type==1}">置顶</button>
<button type="button" class="btn btn-danger btn-sm" id="wonderfulBtn"
th:disabled="${post.status==1}">加精</button>
<button type="button" class="btn btn-danger btn-sm" id="deleteBtn"
th:disabled="${post.status==2}">删除</button>
</div>
定义js文件
- 请求之前已经设置了csrf,异步请求均会带上csrf的token
- 根据按钮的id属性定义对应不同的操作函数
- 异步请求成功后的处理
- 对于帖子的修改操作,异步请求成功后,将按钮的属性改为不可用
- 对于帖子的删除操作,异步请求成功后,直接重定向到首页
var header = $("meta[name='_csrf_header']").attr("content");
var token = $("meta[name='_csrf']").attr("content");
$(document).ajaxSend(function (e, xhr, options) {
xhr.setRequestHeader(header, token);
});
$(function(){
$("#topBtn").click(setTop);
$("#wonderfulBtn").click(setWonderful);
$("#deleteBtn").click(setDelete);
});
function like(btn, entityType, entityId, entityUserId, postId) {
$.post(
CONTEXT_PATH + "/like",
{"entityType":entityType,"entityId":entityId,"entityUserId":entityUserId,"postId":postId},
function (data) {
data = $.parseJSON(data);
if(data.code == 0) {
$(btn).children("i").text(data.likeCount);
$(btn).children("b").text(data.likeStatus == 1 ? '已赞' : '赞');
} else {
alert(data.msg);
}
}
);
}
function setTop() {
$.post(
CONTEXT_PATH + "/discuss/top",
{"id":$("#postId").val()},
function(data) {
data = $.parseJSON(data);
if(data.code == 0) {
$("#topBtn").attr("disabled", "disabled");
} else {
alert(data.msg);
}
}
);
}
function setWonderful() {
$.post(
CONTEXT_PATH + "/discuss/wonderful",
{"id":$("#postId").val()},
function(data) {
data = $.parseJSON(data);
if(data.code == 0) {
$("#wonderfulBtn").attr("disabled", "disabled");
} else {
alert(data.msg);
}
}
);
}
function setDelete() {
$.post(
CONTEXT_PATH + "/discuss/delete",
{"id":$("#postId").val()},
function(data) {
data = $.parseJSON(data);
if(data.code == 0) {
location.href = CONTEXT_PATH + "/index";
} else {
alert(data.msg);
}
}
);
}
测试结果显示:
二、权限管理设置
1. Security权限分配设置
- 本项目设计的方案是:
- 对帖子的加精和置顶,只有版主权限才能访问操作
- 对帖子的删除,只有管理员权限才能访问操作
.antMatchers(
"/discuss/top",
"/discuss/wonderful"
)
.hasAnyAuthority(AUTHORITY_MODERATOR)
.antMatchers("/discuss/delete")
.hasAnyAuthority(AUTHORITY_ADMIN)
2. Thymeleaf模板整合SpringSecurity根据权限动态显示按钮
导入jar包
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
处理模板
xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
-
在按钮标签上添加权限管理
- 与
HttpSecurity 配置的权限管理原理一样,
- 只有指定分配的权限才显示该标签,权限不够不能点击此按钮
测试结果显示
-
普通用户没有权限,不会显示三个按钮 -
版主,可以显示置顶和加精按钮 -
管理员,可以显示删除按钮,并由权限操作
|