赞
踩
2023-7-28 21:18:08
以下内容源自【Java面试项目】
仅供学习交流使用
一:构建敏感词的前缀树
二:过滤文本
SensitiveFilter
package com.jsss.community.util; import org.apache.commons.lang3.CharUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import java.io.*; import java.util.HashMap; import java.util.Map; @Component public class SensitiveFilter { private static final Logger logger= LoggerFactory.getLogger(SensitiveFilter.class); // 替换符 private static final String REPLACEMENT="***"; //根节点 private TrieNode rootNode=new TrieNode(); @PostConstruct public void init(){ try ( InputStream is = this.getClass().getClassLoader().getResourceAsStream("sensitive-words.txt"); BufferedReader reader=new BufferedReader(new InputStreamReader(is)); ){ String keyword; while ((keyword = reader.readLine())!=null){ //添加到前缀树 this.addKeyword(keyword); } } catch (IOException e) { logger.error("加载敏感词文件失败"+e.getMessage()); } } //将一个敏感词添加到前缀树中 private void addKeyword(String keyword) { TrieNode tempNode=rootNode; for (int i = 0; i < keyword.length(); i++) { char c = keyword.charAt(i); TrieNode subNode = tempNode.getSubNode(c); if (subNode==null){ //初始化子节点 subNode=new TrieNode(); tempNode.addSubNode(c,subNode); } //指针指向子节点,进入下一轮循环 tempNode=subNode; //设置结束表示 if (i==keyword.length()-1){ tempNode.setKeyWordEnd(true); } } } /** * 过滤敏感词 * @param text 待过滤的文本 * @return 过滤后的文本 */ public String filter(String text){ if (StringUtils.isBlank(text)){ return null; } //指针1 TrieNode tempNode = rootNode; //指针2 int begin=0; //指针3 int position=0; //结果 StringBuilder sb=new StringBuilder(); while (position<text.length()){ char c=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; }else if (tempNode.isKeyWordEnd()){ //发现敏感词,将begin~position字符串替换掉 sb.append(REPLACEMENT); //进入下一个位置 begin=++position; //重新指向根节点 tempNode=rootNode; }else { //检查下一个字符 ++position; } } //将最后一批字符计入结果,当指针3提前结束 sb.append(text.substring(begin)); return sb.toString(); } //判断是否为符号 private boolean isSymbol(Character c){ //0x2E80~0x9FFF 东亚文字范围 return !CharUtils.isAsciiAlphanumeric(c) &&(c<0x2E80||c>0x9FFF); } //前缀树 private class TrieNode{ //关键词结束标识 private boolean keyWordEnd =false; //子节点(key是下级字符,value是下级结点) private Map<Character,TrieNode> subNodes =new HashMap<>(); public TrieNode() { } public void setKeyWordEnd(boolean keyWordEnd) { this.keyWordEnd = keyWordEnd; } public boolean isKeyWordEnd() { return keyWordEnd; } //添加子节点 public void addSubNode(Character c,TrieNode node){ subNodes.put(c,node); } //获取子节点 public TrieNode getSubNode(Character c){ return subNodes.get(c); } } }
测试:
SensitiveTests
package com.jsss.community; import com.jsss.community.util.SensitiveFilter; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ContextConfiguration; @SpringBootTest @ContextConfiguration(classes = CommunityApplication.class) public class SensitiveTests { @Autowired private SensitiveFilter sensitiveFilter; @Test public void testSensitiveFilter(){ String text="这里可以唱,可以☆跳☆,可以☆rap☆,可☆以☆篮☆球☆,哈哈哈!"; String filter = sensitiveFilter.filter(text); System.out.println(filter); // 这里可以***,可以☆***☆,可以☆***☆,可☆以☆***☆,哈哈哈! } }
sensitive-words.txt
唱
跳
rap
篮球
@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,"你还没有登录"); } 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); //点赞数量 long likeCount =likeService.findEntityLikeCount(ENTITY_TYPE_POST,discussPostId); model.addAttribute("likeCount",likeCount); //点赞状态 int likeStatus=hostHolder.getUser()==null?0: likeService.findEntityLikeStatus(hostHolder.getUser().getId(),ENTITY_TYPE_POST,discussPostId); model.addAttribute("likeStatus",likeStatus); //评论的分页信息 page.setLimit(5); page.setPath("/discuss/detail/"+discussPostId); page.setRows(post.getCommentCount()); //评论:给帖子的评论 //回复:给评论的评论 //评论列表 List<Comment> commentList = commentService.findCommentsByEntity( CommunityConstant.ENTITY_TYPE_POST, post.getId(), page.getOffset(), page.getLimit()); //评论VO列表 List<Map<String,Object>> commentVoList =new ArrayList<>(); if (commentVoList !=null){ for(Comment comment:commentList){ //评论VO Map<String,Object> commentVo =new HashMap<>(); //评论 commentVo.put("comment",comment); //作者 commentVo.put("user",userService.findUserById(comment.getUserId())); //点赞数量 likeCount =likeService.findEntityLikeCount(ENTITY_TYPE_COMMENT,comment.getId()); commentVo.put("likeCount",likeCount); //点赞状态 likeStatus=hostHolder.getUser()==null?0: likeService.findEntityLikeStatus(hostHolder.getUser().getId(),ENTITY_TYPE_COMMENT,comment.getId()); commentVo.put("likeStatus",likeStatus); //回复列表 List<Comment> replyList = commentService.findCommentsByEntity( CommunityConstant.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); //点赞数量 likeCount =likeService.findEntityLikeCount(ENTITY_TYPE_COMMENT,reply.getId()); replyVo.put("likeCount",likeCount); //点赞状态 likeStatus=hostHolder.getUser()==null?0: likeService.findEntityLikeStatus(hostHolder.getUser().getId(),ENTITY_TYPE_COMMENT,reply.getId()); replyVo.put("likeStatus",likeStatus); replyVoList.add(replyVo); } } commentVo.put("replys",replyVoList); //回复的数量 int replyCount = commentService.findCommentCount(CommunityConstant.ENTITY_TYPE_COMMENT, comment.getId()); commentVo.put("replyCount",replyCount); commentVoList.add(commentVo); } } model.addAttribute("comments",commentVoList); return "site/discuss-detail"; }
@RequestMapping(path = "/add/{discussPostId}", method = RequestMethod.POST)
public String addComment(@PathVariable("discussPostId") int discussPostId, Comment comment) {
comment.setUserId(hostHolder.getUser().getId());
comment.setStatus(0);
comment.setCreateTime(new Date());
commentService.addComment(comment);
return "redirect:/discuss/detail/" + discussPostId;
}
// 私信列表 @RequestMapping(path = "/letter/list", method = RequestMethod.GET) public String getLetterList(Model model, Page page) { User user = hostHolder.getUser(); // 分页信息 page.setLimit(5); page.setPath("/letter/list"); page.setRows(messageService.findConversationCount(user.getId())); // 会话列表 List<Message> conversationList = messageService.findConversations( user.getId(), page.getOffset(), page.getLimit()); List<Map<String, Object>> conversations = new ArrayList<>(); if (conversationList != null) { for (Message message : conversationList) { Map<String, Object> map = new HashMap<>(); map.put("conversation", message); map.put("letterCount", messageService.findLetterCount(message.getConversationId())); map.put("unreadCount", messageService.findLetterUnreadCount(user.getId(), message.getConversationId())); int targetId = user.getId() == message.getFromId() ? message.getToId() : message.getFromId(); map.put("target", userService.findUserById(targetId)); conversations.add(map); } } model.addAttribute("conversations", conversations); // 查询未读消息数量 int letterUnreadCount = messageService.findLetterUnreadCount(user.getId(), null); model.addAttribute("letterUnreadCount", letterUnreadCount); int noticeUnreadCount = messageService.findNoticeUnreadCount(user.getId(), null); model.addAttribute("noticeUnreadCount", noticeUnreadCount); return "site/letter"; }
@RequestMapping(path = "/letter/send", method = RequestMethod.POST) @ResponseBody public String sendLetter(String toName, String content) { User target = userService.findUserByName(toName); if (target == null) { return CommunityUtil.getJSONString(1, "目标用户不存在!"); } Message message = new Message(); message.setFromId(hostHolder.getUser().getId()); message.setToId(target.getId()); if (message.getFromId() < message.getToId()) { message.setConversationId(message.getFromId() + "_" + message.getToId()); } else { message.setConversationId(message.getToId() + "_" + message.getFromId()); } message.setContent(content); message.setCreateTime(new Date()); messageService.addMessage(message); return CommunityUtil.getJSONString(0); }
package com.jsss.community.controller.advice; import com.jsss.community.util.CommunityUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @ControllerAdvice(annotations = Controller.class) public class ExceptionAdvice { private static final Logger logger = LoggerFactory.getLogger(ExceptionAdvice.class); @ExceptionHandler({Exception.class}) public void handleException(Exception e, HttpServletRequest request, HttpServletResponse response) throws IOException { logger.error("服务器发生异常: " + e.getMessage()); for (StackTraceElement element : e.getStackTrace()) { logger.error(element.toString()); } String xRequestedWith = request.getHeader("x-requested-with"); if ("XMLHttpRequest".equals(xRequestedWith)) { response.setContentType("application/plain;charset=utf-8"); PrintWriter writer = response.getWriter(); writer.write(CommunityUtil.getJSONString(1, "服务器异常!")); } else { response.sendRedirect(request.getContextPath() + "/error"); } } }
package com.jsss.community.aspect; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.text.SimpleDateFormat; import java.util.Date; //@Component //@Aspect public class ServiceLogAspect { private static final Logger logger = LoggerFactory.getLogger(ServiceLogAspect.class); @Pointcut("execution(* com.jsss.community.service.*.*(..))") public void pointcut() { } @Before("pointcut()") public void before(JoinPoint joinPoint) { // 用户[1.2.3.4],在[xxx],访问了[com.jsss.community.service.xxx()]. ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); if (attributes == null) { return; } HttpServletRequest request = attributes.getRequest(); String ip = request.getRemoteHost(); String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); String target = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName(); logger.info(String.format("用户[%s],在[%s],访问了[%s].", ip, now, target)); } }
这篇博客能写好的原因是:站在巨人的肩膀上
这篇博客要写好的目的是:做别人的肩膀
开源:为爱发电
学习:为我而行
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。