评论
社区最核心的功能就是发布帖子,评论等
首先Entity
publicclassDiscussPost {
@Id
privateintid;
@Field(type=FieldType.Integer)
privateintuserId;
@Field(type=FieldType.Text, analyzer="ik_max_word", searchAnalyzer="ik_smart")
privateStringtitle;
@Field(type=FieldType.Text, analyzer="ik_max_word", searchAnalyzer="ik_smart")
privateStringcontent;
@Field(type=FieldType.Integer)
privateinttype;
@Field(type=FieldType.Integer)
privateintstatus;
@Field(type=FieldType.Date)
privateDatecreateTime;
@Field(type=FieldType.Integer)
privateintcommentCount;
@Field(type=FieldType.Double)
privatedoublescore;
当然field注解后面做这个es搜索要用。
DAO(mapper写点sql语句就行了,略)
@Mapper
publicinterfaceDiscussPostMapper {
List<DiscussPost>selectDiscussPosts(intuserId, intoffset, intlimit);
// @Param注解用于给参数取别名
intselectDiscussPostRows(@Param("userId") intuserId);
intinsertDiscussPost(DiscussPostdiscussPost);
DiscussPostselectDiscussPostById(intid);
intupdateCommentCount(intid, intcommentCount);
}
然后service
publicintaddDiscussPost(DiscussPostpost) {
if (post==null) {
thrownewIllegalArgumentException("参数不能为空!");
}
// 转义HTML标记
post.setTitle(HtmlUtils.htmlEscape(post.getTitle()));
post.setContent(HtmlUtils.htmlEscape(post.getContent()));
// 过滤敏感词
post.setTitle(sensitiveFilter.filter(post.getTitle()));
post.setContent(sensitiveFilter.filter(post.getContent()));
returndiscussPostMapper.insertDiscussPost(post);
}
这里过滤敏感词是前缀树实现的,
privateclassTrieNode {
// 关键词结束标识
privatebooleanisKeywordEnd=false;
// 子节点(key是下级字符,value是下级节点)
privateMap<Character, TrieNode>subNodes=newHashMap<>();
publicbooleanisKeywordEnd() {
returnisKeywordEnd;
}
publicvoidsetKeywordEnd(booleankeywordEnd) {
isKeywordEnd=keywordEnd;
}
// 子节点
publicvoidaddSubNode(Characterc, TrieNodenode) {
subNodes.put(c, node);
}
// 获取子节点
publicTrieNodegetSubNode(Characterc) {
returnsubNodes.get(c);
}
}
将一个敏感词加入前缀树
privatevoidaddKeyword(Stringkeyword) {
TrieNodetempNode=rootNode;
for (inti=0; i<keyword.length(); i++) {
charc=keyword.charAt(i);
TrieNodesubNode=tempNode.getSubNode(c);
if (subNode==null) {
// 初始化子节点
subNode=newTrieNode();
tempNode.addSubNode(c, subNode);
}
// 指向子节点,进入下一轮循环
tempNode=subNode;
//设置结束标识
if (i==keyword.length() -1) {
tempNode.setKeywordEnd(true);
}
}
}
过滤的内容,三个指针开始遍历,遇到敏感词替换为***
publicStringfilter (Stringtext) {
if (StringUtils.isBlank(text)) {
returnnull;
}
// 指针1
TrieNodetempNode=rootNode;
// 指针2
intbegin=0;
// 指针3
intposition=0;
// 结果
StringBuildersb=newStringBuilder();
while (position<text.length()) {
charc=text.charAt(position);
// 跳过符号
if (isSymbol(c)) {
// 若指针1处于根节点,将此符号计入结果,让指针2向下走一步
if (tempNode==rootNode) {
sb.append(c);
begin++;
}
// 无论符号在开头或中间,指针3都向下走一步
position++;
continue;
}
tempNode=tempNode.getSubNode(c);
if (tempNode==null) {
// 以begin为开头的不是敏感词
sb.append(text.charAt(begin));
position=++begin;
tempNode=rootNode;
} elseif (tempNode.isKeywordEnd()) {
// 发现敏感词
sb.append(REPLACEMENT);
begin=++position;
} else {
position++;
}
}
sb.append(text.substring(begin));
returnsb.toString();
}
然后发帖的controller层
@RequestMapping(path="/add", method=RequestMethod.POST)
@ResponseBody
publicStringaddDiscussPost(Stringtitle, Stringcontent) {
Useruser=hostHolder.getUser();
if (user==null) {
returnCommunityUtil.getJSONString(403, "您还没有登录~");
}
DiscussPostpost=newDiscussPost();
post.setUserId(user.getId());
post.setTitle(title);
post.setContent(content);
post.setCreateTime(newDate());
discussPostService.addDiscussPost(post);
returnCommunityUtil.getJSONString(0, "发布成功!");
}