问题描述
使用netty构造服务端,使用浏览器在地址栏输入访问地址时,除了会发送目标url之外,浏览器还会额外发送一个url–>/favicon.ico,以前是在一个业务处理的hanlder中使用if判断uri,如果uri是这个的话,就不去执行业务逻辑,但是这样的话会造成业务代码与判断逻辑的耦合。所以使用一个新的handler去处理,利用netty的执行连完成后序的业务。
handler的构造执行顺序如下
HttpRequestDecoder(netty自带)–>FilterurlHandler–>HttpNettyRequestDecoder(二次解码器,自定义)–>serviceHandler(业务handler)–>HttpNettyResponseEncoder(二次编码器,自定义)–>HttpResponseEncoder(netty自带)
其中filterurlhandler,serviceHandler继承SimpleChannelInboundHandler


但是当浏览器访问的时候,比如url【/queryapi?index=1】,浏览器可以收到netty服务端返回的信息,但是netty的控制台会抛出异常
postman模拟发送

控制台异常如下

而且根据异常的堆栈信息也可以看出,里面没有涉及到自己编写的业务代码。
排查
首先是filterUnuseHandler,通过代码执行,可以看到,该handler已经生效了(注意红圈中的FullRequest对象的内存地址,稍微会用到),并且通过调用firechannelRead方法通知下一个符合入参的handler

上述firechannelRead通知的handler是二次解码器HttpNettyRequestDecoder,该类是继承SimpleChannelInboundHandler。
根据执行链进入到MessageToMessageDecoder.channelRead方法

HttpNettyRequestDecoder继承的就是这个类,并且实现了decode方法
会过来继续看MessageToMessageDecoder.channelRead方法

idea断点信息

根据代码可知,cast是msg的一个备份,在decode二次解码之后,在finally中被释放
同时,在channelRead方法的finally块中,继续执行责任链,注意入参,此时已经变成了HttpNettyRequest(二次解码后我们自定义的对象),因为我们在二次解码器中完成解码之后,需要将二次解码对象加入到list中(所以这个意思就是寻找下一个handler,并且该handler的一个入参的类型是HttpNettyRequest)

firechannelRead的执行顺序还是和上面说的一样
最终进入到业务handler中,执行代码(注意,此时原先的那个request对象依然存在在内存中,DefaultFullHttpRequest@2416,没有被释放)
业务代码具体执行就不说了,业务类是继承SimpleChannelInboundHandler,最终业务handler中生成了业务消息,需要将其编码为HttpRespone,但是此时是HttpNettyResponse(我们自定义的对象)。
编码过程(HttpNettyResponse–>HttpResponse)与request的二次解码过程类似,也是netty在业务代码执行完之后,获得了HttpNettyResponse对象,需找handler,该handler的入参是HttpNettyResponse,进行二次编码,最终代码回到FilterUnuseUrl中

注意红圈内,原先的request对象依旧存在
执行下一步,退出了重写方法MessageReceived。由于之前说过,FilterUnuseUrl是继承SimpleChannelInboundHandler类的,所以返回到父类中

这个finally是不是很熟悉,之前也看到过。同时看finally中释放的msg的地址,就是我们一开始说留意的那个request对象,所以在finally中,request对象又被释放
所以request对象被释放了两次,所以会抛出异常。
解决办法
过滤url的handler不要继承SimpleChannelInboundHandler,直接继承ChannelHandlerAdaptor即可。因为request的第一次被释放引用是在MessageToMessage中,暨二次解码完毕后,但是这是没法改的,所以直接继承适配器类,避免二次释放request

最后,不知道这算不算netty的一个bug,就是不能二次解码器继承MessageToMessageDecoder,同时另外一个类继承SimpleChannelInboudHandler,会抛非法引用异常

netty自定义url过滤器抛引用异常相关推荐

  1. shiro学习系列:shiro自定义filter过滤器

    shiro学习系列:shiro自定义filter过滤器 自定义JwtFilter的hierarchy(层次体系) 上代码 package com.finn.springboot.common.conf ...

  2. Django框架学习20--模板变量,模板标签,模板过滤器及自定义模板过滤器,自定义模板标签

    1.模板变量 string 字符串和 int 类型,通过key名称直接取值,如:{{ n_name }} list类型的取值,通过点下班取值,如:{{ fancy.0 }}.{{ fancy.1 }} ...

  3. java创建对象过七夕,想 new 个对象过七夕,她却抛了异常

    原标题:想 new 个对象过七夕,她却抛了异常 关注 "" 导读:单身之痛...... 作者 | 轩辕之风 来源 | 编程技术宇宙(ID:xuanyuancoding) 七夕又到了 ...

  4. java url 协议_Java自定义URL协议

    Java提供了对URL协议进行扩展的能力,通过扩展用户可以自定义URL通信协议,JDK默认提供了对HTTP,FTP,JAR,FILE等的实现,而当需要自己定义通信协议的时候,就需要利用JDK提供的对U ...

  5. 新浪开放平台:解决获取access_token抛 21323 异常,以及接口调用

    使用新浪开放平台的准备 1)要注册一个新浪微博,并在新浪开放平台登陆(http://open.weibo.com/)     2)创建应用          这里以创建"移动应用" ...

  6. Gateway自定义全局过滤器

    一.Gateway全局过滤器 1.全局过滤器(Global Filters)简介 Gateway过滤器在实现方式上,有两种过滤器: GatewayFilter(局部过滤器/网关过滤器): 需要通过 s ...

  7. netty自定义channel id

    netty自定义channel id.netty custom channel id 搞搞netty时发现默认的id很长,无法直接自定义. 于是我网上搜索了search一下,发现没有相关文章,那就自己 ...

  8. Netty 自定义编码解码器

    Netty 自定义编码解码器 入栈:InboundHandler ,出栈:OutboundHandler.Netty 构建 chain 来处理业务. 自定义一个解码器 解码器主要是对客户端发送的消息进 ...

  9. Unity 之 NullReferenceException(空引用异常)问题

    什么是NullReferenceException(空引用异常)? 来自官方的诠释:https://docs.unity3d.com/Manual/NullReferenceException.htm ...

最新文章

  1. win10 64位SSDT函数索引动态查找
  2. WPF入门:数据绑定
  3. netty tcp服务端主动断开客户端_【Netty】服务端和客户端
  4. 4.3---建立高度最小二叉树
  5. Linux下Makefile学习笔记
  6. c++11 yield函数的使用
  7. mysql删除注册表mysqld要删除吗_删库就一定要跑路吗?rm删除文件后空间还存在似乎说明了什么...
  8. VS2012 安装番茄助手
  9. Windows10环境中下载DOSBox并进行debug配置
  10. VS2008 安装顺序
  11. 2G/3G LAC与4G/5G TAC的协同优化
  12. 常见bugger集合
  13. chrome插件安装方法教程
  14. Xilinx AXI Crossbar相关调试记录
  15. 火山火花代码编辑框(火花编辑框)Scintilla代码编辑框案例教程
  16. Java 集成阿里大鱼平台短信服务发送验证码 --- 补齐注册部分
  17. 解决使用DevStack 安装 OpenStack 重启后br-ex失效的问题
  18. 神经网络与深度学习笔记 (五)深层神经网络
  19. 如何优雅地删除Docker镜像和容器(超详细)
  20. 大数据集群迁移的那一夜是怎么过的|回忆录

热门文章

  1. 新买的笔记本首先该做什么?
  2. Excel学习笔记一Excel图表和数据分析
  3. QT制作电池电量图标
  4. 【LeGO-LOAM论文阅读(三)--地图优化】
  5. 1024分论坛:数字化转型和工业互联网的痛点、共识和远见
  6. 分享聚宽量化交易执行选股策略的执行过程
  7. 微信公众号批量推送java_微信批量关注公众号、推送消息的方法!
  8. GDUT 专题四 H - 跳蚤 (数学)2022
  9. 如何反注册DLL文件
  10. Apache Flink流处理(五)