为实现发布帖子功能需要 异步请求
异步请求 即当前网页不刷新的前提下,访问服务器,服务器会给我们返回一些结果。用此结果对网页进行局部刷新。
实现异步请求 的技术AJAX
在CommunityUtil下,新建几个方法
首先导入这个包
并粘贴到porn中
之后新建如下方法
public static String getJSONString(int code, String msg, Map<String, Object> map) {
JSONObject json = new JSONObject();
json.put("code", code);
json.put("msg", msg);
if (map != null) {
for (String key : map.keySet()) {//遍历map中的key
json.put(key, map.get(key));//把该key 传入json
}
}//经过上述代码,json里面封装了code msg Map等
return json.toJSONString();//接着,将json 转换为json格式的字符串
}
//以下,对getJSONString方法进行重载,便于调用
public static String getJSONString(int code, String msg) {
return getJSONString(code, msg, null);
}
public static String getJSONString(int code) {
return getJSONString(code, null, null);
}
public static void main(String[] args) {
Map<String, Object> map = new HashMap<>();
map.put("name", "zhangsan");
map.put("age", 25);
System.out.println(getJSONString(0, "ok", map));
}
}
打印结果:
接着在AlphaController里写ajax示例
// ajax示例
@RequestMapping(path = "/ajax", method = RequestMethod.POST)
@ResponseBody//因为返回的是字符串,所以要用此注解
public String testAjax(String name, int age) {
System.out.println(name);
System.out.println(age);
return CommunityUtil.getJSONString(0, "操作成功!");
}
然后写一个静态网页ajax-demo.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>AJAX</title>
</head>
<body>
<p>
<input type="button" value="发送" onclick="send();">
</p>
<script src="https://code.jquery.com/jquery-3.3.1.min.js" crossorigin="anonymous"></script> <!-- 引入jquery -->
<script>
function send() {<!-- 实现send方法 -->
$.post(<!-- post方法要有三个参数 -->
"/community/alpha/ajax", <!-- 访问路径 -->
{"name":"张三","age":23},<!-- 要向服务器提交的参数 -->
function(data) { <!-- 声明一个匿名回调函数 -->
console.log(typeof(data)); <!--data是服务器返回给浏览器的数据 --> <!-- 在控制台查看data的类型 -->
console.log(data);<!-- 在控制台 查看data内容 -->
data = $.parseJSON(data); <!-- data变为 js对象-->
console.log(typeof(data));<!-- 在控制台查看data的类型 -->
console.log(data.code);<!-- 访问data里的code -->
console.log(data.msg);
}
);
}
</script>
</body>
</html>
写完以后,测试 community application
点击发送返回的结果
通过这个小实例。开发 发布帖子 功能
DiscussPostMapper之前声明了查询方法
现在增加 发布帖子方法
int insertDiscussPost(DiscussPost discussPost);
打开DiscussPostMapper
<sql id="insertFields">
user_id, title, content, type, status, create_time, comment_count, score
</sql>
<insert id="insertDiscussPost" parameterType="DiscussPost">
insert into discuss_post(<include refid="insertFields"></include>) <!-- 引入前述insertFields中的参数-->
values(#{userId},#{title},#{content},#{type},#{status},#{createTime},#{commentCount},#{score})
</insert>
之后在DiscussPostService中追加方法addDiscussPost:
public int addDiscussPost(DiscussPost post) {
if (post == null) {
throw new IllegalArgumentException("参数不能为空!");
}
// 把标签 转义为HTML标记 比如<,>
post.setTitle(HtmlUtils.htmlEscape(post.getTitle()));
post.setContent(HtmlUtils.htmlEscape(post.getContent()));
// 对Post进行过滤敏感词
post.setTitle(sensitiveFilter.filter(post.getTitle()));
post.setContent(sensitiveFilter.filter(post.getContent()));
return discussPostMapper.insertDiscussPost(post);
}
public DiscussPost findDiscussPostById(int id) {
return discussPostMapper.selectDiscussPostById(id);
}
public int updateCommentCount(int id, int commentCount) {
return discussPostMapper.updateCommentCount(id, commentCount);
}
接下来添加视图层:
新建DiscussPostController类
package com.nowcoder.community.controller;
import com.nowcoder.community.entity.Comment;
import com.nowcoder.community.entity.DiscussPost;
import com.nowcoder.community.entity.Page;
import com.nowcoder.community.entity.User;
import com.nowcoder.community.service.CommentService;
import com.nowcoder.community.service.DiscussPostService;
import com.nowcoder.community.service.UserService;
import com.nowcoder.community.util.CommunityConstant;
import com.nowcoder.community.util.CommunityUtil;
import com.nowcoder.community.util.HostHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.*;
@Controller
@RequestMapping("/discuss")
public class DiscussPostController implements CommunityConstant {
@Autowired
private DiscussPostService discussPostService;
@Autowired
private HostHolder hostHolder;//从这里要取出hostHolder
@Autowired
private UserService userService;
@Autowired
private CommentService commentService;
@RequestMapping(path = "/add", method = RequestMethod.POST)
@ResponseBody
public String addDiscussPost(String title, String content) {
User user = hostHolder.getUser();
if (user == null) {
return CommunityUtil.getJSONString(403, "你还没有登录哦!");//403代表没有权限
}
DiscussPost post = new DiscussPost();
post.setUserId(user.getId());
post.setTitle(title);
post.setContent(content);
post.setCreateTime(new Date());//对象构造好以后
discussPostService.addDiscussPost(post);
// 报错的情况,将来统一处理.而不在这里一个个处理。
return CommunityUtil.getJSONString(0, "发布成功!");
}
@RequestMapping(path = "/detail/{discussPostId}", method = RequestMethod.GET)
public String getDiscussPost(@PathVariable("discussPostId") int discussPostId, Model model, Page page) {
// 帖子
DiscussPost post = discussPostService.findDiscussPostById(discussPostId);
model.addAttribute("post", post);
// 作者
User user = userService.findUserById(post.getUserId());
model.addAttribute("user", user);
// 评论分页信息
page.setLimit(5);
page.setPath("/discuss/detail/" + discussPostId);
page.setRows(post.getCommentCount());
// 评论: 给帖子的评论
// 回复: 给评论的评论
// 评论列表
List<Comment> commentList = commentService.findCommentsByEntity(
ENTITY_TYPE_POST, post.getId(), page.getOffset(), page.getLimit());
// 评论VO列表
List<Map<String, Object>> commentVoList = new ArrayList<>();
if (commentList != null) {
for (Comment comment : commentList) {
// 评论VO
Map<String, Object> commentVo = new HashMap<>();
// 评论
commentVo.put("comment", comment);
// 作者
commentVo.put("user", userService.findUserById(comment.getUserId()));
// 回复列表
List<Comment> replyList = commentService.findCommentsByEntity(
ENTITY_TYPE_COMMENT, comment.getId(), 0, Integer.MAX_VALUE);
// 回复VO列表
List<Map<String, Object>> replyVoList = new ArrayList<>();
if (replyList != null) {
for (Comment reply : replyList) {
Map<String, Object> replyVo = new HashMap<>();
// 回复
replyVo.put("reply", reply);
// 作者
replyVo.put("user", userService.findUserById(reply.getUserId()));
// 回复目标
User target = reply.getTargetId() == 0 ? null : userService.findUserById(reply.getTargetId());
replyVo.put("target", target);
replyVoList.add(replyVo);
}
}
commentVo.put("replys", replyVoList);
// 回复数量
int replyCount = commentService.findCommentCount(ENTITY_TYPE_COMMENT, comment.getId());
commentVo.put("replyCount", replyCount);
commentVoList.add(commentVo);
}
}
model.addAttribute("comments", commentVoList);
return "/site/discuss-detail";
}
}
在首页点击“发布帖子” 才能发布。
在index.html中进行了一些修改
因为 最后依赖的js是:
<script th:src="@{js/index.js}"></script>
所以在index.js中进行如下编辑:见视频:40.59
$(function(){
$("#publishBtn").click(publish);
});
function publish() {
$("#publishModal").modal("hide");
// 获取标题和内容
var title = $("#recipient-name").val();
var content = $("#message-text").val();
// 发送异步请求(POST)
$.post(
CONTEXT_PATH + "/discuss/add",
{"title":title,"content":content},
function(data) {//回调函数处理返回的结果
data = $.parseJSON(data);//转换为对象
$("#hintBody").text(data.msg);// 在提示框中显示返回消息。根据id $("#hintBody")获取提示框,利用text方法修改内容
$("#hintModal").modal("show"); // 显示提示框
// 2秒后,自动隐藏提示框
setTimeout(function(){
$("#hintModal").modal("hide");
// == 0,表示成功,需要刷新页面
if(data.code == 0) {
window.location.reload();
}
}, 2000);
}
);
}
验证:
没有登录的时候,不显示 “发布帖子”
在index.html中实现:
<button type="button" class="btn btn-primary btn-sm position-absolute rt-0" data-toggle="modal" data-target="#publishModal" th:if="${loginUser!=null}">我要发布</button> <!-- 判断登录是否为空,因为只有 登录时才能 点击我要发布-->
先登录:
登录后出现我要发布
数据库中也有该数据
包含敏感词时:
小于号不再是标签,而是一个个文本
且过滤掉敏感词。