第三章:过滤敏感词、帖子管理

过滤敏感词

image-20211209143339501

image-20211209144103952

根节点没有字符,到最末节点拼起来才是敏感字符,做一个标记在最后。

image-20211209144224791

image-20211209145020986

image-20211209154151059

过滤符号

/*
* 过滤敏感词
* 参数:待过滤的文本,  返回过滤后的文本
* */
public String filter(String text){
    // 参数空值判断
    if(StringUtils.isBlank(text)){
        return null;
    }
    //依赖三个指针去过滤
    TrieNode tempNode=rootNode; //指针一
    int begin=0;   //指针二
    int position=0;   //指针三

    //变量记录最后的结果,变长
    StringBuilder sb=new StringBuilder();

    // 利用指针三做条件
    while (begin<text.length()){
        if(position<text.length()){
            //得到指针三的字符
            char c = text.charAt(position);
            //跳过符号(跳过敏感词汇里面有符号)
            if(isSymbol(c)){
                //若指针一属于根节点,将此符号计入结果,让指针2向下走
                if(tempNode==rootNode){
                    begin++;
                    sb.append(c);
                }
                //无论符号在开头或中间,指针3都向下走一步
                position++;
                //跳过符号下面的业务就不用处理了,到此为止
                continue;
            }
            //字符不是符号,检查下级节点
            //去下级节点
            tempNode = tempNode.getSubNode(c);

            //当下级没有节点,即以begin开头的字符串不是敏感词,将其添加到结果中
            if(tempNode==null){
                sb.append(text.charAt(begin));
                //指针2后移,且指针3与其保持一致
                begin++;
                position=begin;
                //重新指向根节点
                tempNode=rootNode;

            }else if(tempNode.isKeywordEnd()){//当当前节点是最后
                //发现敏感词,将beagin~position字符串替换掉
                sb.append(REPLACEMENT);
                //position下移,并且指针2与其保持一致
                position++;
                begin=position;
                //重新指向根节点
                tempNode=rootNode;
            }else {
                //检查下一个字符
                if(position<text.length()-1){
                    position++;
                }

            }

        }

    }
    //将最后一批字符计入结果
    sb.append(text.substring(begin));
    return sb.toString();
}

/*
* 判断是否为符号
* */
public boolean isSymbol(Character c){
    //利用工具,判断字符是不是普通的字符(abc。。),东亚文字范围中、日、韩文(0x2E80~0x9FFF)
    return !CharUtils.isAsciiAlphanumeric(c) && (c<0x2E80 || c>0x9FFF);
}

发布帖子

异步请求:当前页面不刷新,去访问服务器,返回结果提炼数据对网页进行局部刷新(提示,更改样式等)

image-20211209185051345

image-20211209190127207

image-20211209190306107

完成前后端交互,data服务器返回的数据

image-20211210093801552

image-20211210093954841

插入帖子,从数据层开始。业务层保存帖子,同时过滤敏感词汇

帖子详情

image-20211210110922021

数据:查看帖子方法

事务管理

image-20211210114526778

image-20211210114701652

image-20211210114906057

image-20211210115120923

image-20211210115144909

image-20211210115210551

image-20211210115249953

不可重复读是对一条数据,幻读是对多个数据行数

image-20211210133206657

image-20211210133441138

image-20211210133704554

image-20211210134955517

编程式事务

image-20211210135614676

显示评论

image-20211210141232885

处理楼数显示,要考虑要分页,起始行+循环次数

image-20211210155405203

复用前端代码:

image-20211210161201173

image-20211210161222035

添加评论

image-20211210174429110

image-20211212111217956

image-20211212111232583

私信列表

image-20211212111107430

未读消息和共几条会话。

0:未读 ,1:已读, 2:删除。 会话id(查询会话列表,将两个发送方和接收方id拼起来,将小的id放前面,大的放后面)

数据层:建立实体类

image-20211212112857677

dao层:接口Messagemapper

五个方法:

1,查询这一页的方法(查询当前用户会话列表,针对每个会话只返回一条最新的私信)

2、查询总行数的方法

3、4 :点进去是详情的查询一页的方法及总行数的方法

5:查未读消息数量(查某个用户会话总的未读消息和查询用户与另外一个用户的未读消息数量)

from_id=1表示系统通知

image-20211212121116012

业务层

直接调用mapper实现即可

发送私信

异步请求

image-20211213100805791

当mybatis参数为集合时,用foreach循环

//修改消息状态(将未读变成已读)
int updateMessage(List<Integer> ids,int status);
<update id="updateMessage" >
    update message set status=#{status}
    where id in
    <foreach collection="ids" item="id" open="(" separator="," close=")">
        #{id}
    </foreach>
</update>

删除私信

(修改私信的状态为2)

业务层方法

image-20211213144147567

dao

image-20211213144207258

image-20211213144235777

异步请求js

image-20211213144316576

image-20211213144354936

统一处理异常

image-20211213081702735

@ModelAttributr:给model绑定统一的参数,给所有的controller用

@DataBinder:页面向服务器传参自动的参数转换,例将page转为Page类

image-20211213085912754

@ControllerAdvice(annotations = Controller.class)  //只有带有Controller注解的会被异常处理
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());
        }

        //给浏览器一个响应,浏览器访问服务器可能希望返回页面,或者是异步请求希望返回json
        //需要判断请求是普通请求还是异步请求
        String xRequestedWith = request.getHeader("x-requested-with");
        //返回值等于xml,表示为异步请求(异步希望返回xml,普通希望返回http)
        if("XMLHttpRequest".equals(xRequestedWith)){
            //设置格式为字符串自己转为json
            response.setContentType("application/plain;charset=utf-8");
            PrintWriter writer=response.getWriter();
            writer.write(CommunityUtil.getJSIONString(1,"服务器异常!"));

        }else{
            //普通请求,重定向到错误页面
            response.sendRedirect(request.getContextPath()+"/error");
        }

    }
}

统一记录日志

控制器通知是控制器发生异常时记录日志,拦截器是针对controller控制层的,两个都不合适,

需求:对所有的service记日志。

记录日志是系统需求(业务方法和系统需求不要耦合在一起,以后修改系统需求时不方便)

image-20211213145111387

image-20211213145329508

image-20211213145614142

image-20211213150339886

image-20211213150622139

没有接口时(service业务层)需要CGLib代理

@Around:是在方法前后都进行织入

需要有参数:连接点(代表程序织入的部位)。

image-20211213151852505

@AfterThrowing:是在抛异常之后

@AfterReturning:是在方法返回之后

image-20211213152041851

记录日志:用户(ip)XXX在某时刻使用了XX方法

用工具类获取用户ip

image-20211213160247591

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值