用户发布消息的过滤
必须过滤用户生成的内容,HTML标签过滤 ,HtmlUtils.htmlEscape(进行了转义)
敏感词过滤 使用了字典树Tire Tree(非法的,竞争对手广告)
优点:利用字符串的公共前缀来减少查询时间,最大限度的减少无谓的字符串比较。
字典树3个特性
1 根节点不包含字符,除根节点外每个节点只包含一个字符
2 从根节点到某一节点路径经过的字符连接起来为对应的字符串
3 每个节点的所有子节点包含的字符都不相同
3个指针
1 指向树的指针 TrieNode temp =rootNode;
2 指向字符串的指针(寻找敏感字符串的头) int =begin;
3 指向字符串的指针(当找到头时工作) int = position;
StringBuilder
构造字典树
public class TrieNode{
private boolean end =false;
private string data;
private TrieNode rootNode =new TrieNode();
private Map<Character,TrieNode> subNodes =new HashMap<Character,TrieNodes>();
public void addSubNodes(Charater key ,TrieNode node){
subNodes.put(key,node);
}
public TrieNode getSubNode(Charater key){
return subNodes.get(key)
}
public void setkeywordEnd(boolean end){
this.end=end;
}
}
在字典树中添加单词
private void addWord(String lineTxt){
TrieNode tempNode= rootNode;
for(int i= 0;i<lineTxt.length();++i){
Charater c=lineTxt.charAt(i);
TrieNode node =tempNode.getSubNode(c);
if(node==null){ // 判断根节点的子节点中是否有词节点 ,
tempNode.addSubNodes(c,node); //没有此节点则添加
}
//若有此节点则吧下一节点变为此节点
tempNode=node;
if(i==lineTxt.length()-1) tempNode.setkeywordEnd(true);//若为最后一个节点设置节点结尾标识。
}
}
过滤算法
public String filter (String text){
if(StringUtils.isBlank(text)){return text;}
String replacement="***";
StringBuilder result=new StringBuilder();
TrieNode temp =root;
int begin=0;
int positin=0;
while(position<text.length()){
char c= text.charAt(position);
temp=temp.getSubNodes(c);
if(temp==null){
result.append(text.charAt(begin));
position=begin+1;
begin=position;
temp=rootNode;
}else if(temp.iskeywordEnd()){
}
}
}
项目遇到那些难点?
在测试时发现在网络不好时用户如果多次点击提交 ,可以向数据库提交多条重复数据。增加了数据库的冗余,大量垃圾浪费空间
解决办法,查了下资料有2中解决办法
1用js 设置一下指定时间内表单只能提交1次
2利用session 下发 token
String Stringbuffer(线程安全) Stringbuilder 区别
String 是只读字符串,被final修饰的不可变类
Stringbuffer stringbuilder可以对字符串进行直接修改