netty自定义url过滤器抛引用异常
问题描述
使用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过滤器抛引用异常相关推荐
- shiro学习系列:shiro自定义filter过滤器
shiro学习系列:shiro自定义filter过滤器 自定义JwtFilter的hierarchy(层次体系) 上代码 package com.finn.springboot.common.conf ...
- Django框架学习20--模板变量,模板标签,模板过滤器及自定义模板过滤器,自定义模板标签
1.模板变量 string 字符串和 int 类型,通过key名称直接取值,如:{{ n_name }} list类型的取值,通过点下班取值,如:{{ fancy.0 }}.{{ fancy.1 }} ...
- java创建对象过七夕,想 new 个对象过七夕,她却抛了异常
原标题:想 new 个对象过七夕,她却抛了异常 关注 "" 导读:单身之痛...... 作者 | 轩辕之风 来源 | 编程技术宇宙(ID:xuanyuancoding) 七夕又到了 ...
- java url 协议_Java自定义URL协议
Java提供了对URL协议进行扩展的能力,通过扩展用户可以自定义URL通信协议,JDK默认提供了对HTTP,FTP,JAR,FILE等的实现,而当需要自己定义通信协议的时候,就需要利用JDK提供的对U ...
- 新浪开放平台:解决获取access_token抛 21323 异常,以及接口调用
使用新浪开放平台的准备 1)要注册一个新浪微博,并在新浪开放平台登陆(http://open.weibo.com/) 2)创建应用 这里以创建"移动应用" ...
- Gateway自定义全局过滤器
一.Gateway全局过滤器 1.全局过滤器(Global Filters)简介 Gateway过滤器在实现方式上,有两种过滤器: GatewayFilter(局部过滤器/网关过滤器): 需要通过 s ...
- netty自定义channel id
netty自定义channel id.netty custom channel id 搞搞netty时发现默认的id很长,无法直接自定义. 于是我网上搜索了search一下,发现没有相关文章,那就自己 ...
- Netty 自定义编码解码器
Netty 自定义编码解码器 入栈:InboundHandler ,出栈:OutboundHandler.Netty 构建 chain 来处理业务. 自定义一个解码器 解码器主要是对客户端发送的消息进 ...
- Unity 之 NullReferenceException(空引用异常)问题
什么是NullReferenceException(空引用异常)? 来自官方的诠释:https://docs.unity3d.com/Manual/NullReferenceException.htm ...
最新文章
- win10 64位SSDT函数索引动态查找
- WPF入门:数据绑定
- netty tcp服务端主动断开客户端_【Netty】服务端和客户端
- 4.3---建立高度最小二叉树
- Linux下Makefile学习笔记
- c++11 yield函数的使用
- mysql删除注册表mysqld要删除吗_删库就一定要跑路吗?rm删除文件后空间还存在似乎说明了什么...
- VS2012 安装番茄助手
- Windows10环境中下载DOSBox并进行debug配置
- VS2008 安装顺序
- 2G/3G LAC与4G/5G TAC的协同优化
- 常见bugger集合
- chrome插件安装方法教程
- Xilinx AXI Crossbar相关调试记录
- 火山火花代码编辑框(火花编辑框)Scintilla代码编辑框案例教程
- Java 集成阿里大鱼平台短信服务发送验证码 --- 补齐注册部分
- 解决使用DevStack 安装 OpenStack 重启后br-ex失效的问题
- 神经网络与深度学习笔记 (五)深层神经网络
- 如何优雅地删除Docker镜像和容器(超详细)
- 大数据集群迁移的那一夜是怎么过的|回忆录