当前位置: 首页 > news >正文

thrift:拦截器ThriftEventHandler获取调用参数

之前写过一篇博客《spring:拦截器(HandlerInterceptor)中获取POST请求参数》
介绍了如何在在spring的拦截器一层获取POST请求参数。
当我在thrift环境使用ThriftEventHandler拦截请求获取请求参数,也遇到了类似的问题:

这个阶段,因为请求方法的参数还没有被反序列化,所以要想获取HTTP的请求参数,就要自己从HttpServletRequest中获取。要从请求内容里获取参数,就要从TProtocol里获取到,然后解析出数据就可以了。
  但是,TProtocol读取数据是单向的,一次性的,如果在ThriftEventHandler获取了TProtocol中的数据,后续方法调用解析参数时再读取TProtocol就会失败,因为输入流结束了。
  所以拦截器(ThriftEventHandler)中获取请求参数本身并不是问题,问题就是要解决TProtocol的输入流能被多次读取问题。
  解决的思路与spring拦截的差不多,就是将TProtocol基于TProtocolDecorator封装起来,用封装后的BufferedProtocol替换掉整个请求链路中的TProtocol。
  要实现的BufferedProtocol类负责将TProtocol中的完整数据读取出来保存下来,以便重复读取。
  这样才能确保TProtocol可以多次被读取。
  
以下为BufferedProtocol封装类实现

org.apache.thrift.protocol.BufferedProtocol.java

import org.apache.thrift.transport.AutoExpandingBufferWriteTransport;
import org.apache.thrift.transport.TMemoryInputTransport;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;import java.util.Arrays;/*** 基于{@link TProtocolDecorator}实现{@link TTransport}可重复读取* * @author guyadong* @since 1.3.0**/
public class BufferedProtocol extends TProtocolDecorator {/*** 装饰实例* */public final TProtocol delegate;/*** 从装饰{@link #delegate}中读取的数据缓冲区*/private final byte[] buffer;private BufferedProtocol(TProtocol protocol) {this(protocol,null);}private BufferedProtocol(TProtocol protocol,byte[] buffer) {super(protocol);this.delegate = protocol;try {/*** 读取输入的{@link TTransport}所有数据创建{@link TMemoryInputTransport}实例*/this.buffer = null == buffer ? copy(protocol.getTransport()) : buffer;this.trans_ = new TMemoryInputTransport(this.buffer);this.delegate.trans_ = this.trans_;} catch (TTransportException e) {throw new RuntimeException(e);}}private static byte[] copy(TTransport transport) throws TTransportException {try (AutoExpandingBufferWriteTransport autoExpandingTransport = new AutoExpandingBufferWriteTransport(1024,1.5)) {int readCount;byte[] buffer = new byte[1024];while ((readCount = transport.read(buffer, 0, buffer.length)) > 0) {autoExpandingTransport.write(buffer, 0, readCount);}return Arrays.copyOfRange(autoExpandingTransport.getBuf().array(), 0, autoExpandingTransport.getPos());}}/*** 复位 TTransport, 以支持从 {@link #buffer} 重复读取*/@Overridepublic void reset() {delegate.reset();((TMemoryInputTransport)delegate.trans_).reset(buffer);}public static BufferedProtocol of(TProtocol protocol) {return new BufferedProtocol(protocol);}
}

进一步还要重写ThriftServiceProcessor,将TProtocol替换为BufferedProtocol,这样才能生效。
详细代码不贴了,参见项目仓库。
https://gitee.com/l0km/xthrift/blob/master/xthrift-service/src/main/java/com/facebook/swift/service/XthriftMethodProcessor.java

完整代码

完整代码参见码云仓库:https://gitee.com/l0km/xthrift

相关文章:

  • SpringBoot项目启动后自动执行方法
  • 广州自闭症全托管学校-正规儿童康复中心
  • 利用深度学习技术来实现街景图像的语义分割(街景图像语义分割)
  • 基于WonderJourney生成电影级连续的3D场景视频
  • Java学习Day33:HTML 第四章:大战虎先锋(js)
  • 6个免费字体网站,无需担心版权问题~
  • Android 12系统源码_多屏幕(三)模拟辅助设备功能实现原理
  • GitHub开源的PDF管理工具Stirling-pdf
  • Godot模拟实现多人游戏平滑移动
  • SpringData基础学习
  • vue前端更新后需要清空缓存
  • MySQL中 EXPLAIN 的使用介绍
  • oracle共享池(shared pool):一、工作原理、组成部分 二、软硬解析过程
  • 边界dp注意重叠边界
  • Java使用Tesseract进行OCR图片文字识别
  • CNN 在图像分割中的简史:从 R-CNN 到 Mask R-CNN
  • echarts的各种常用效果展示
  • Eureka 2.0 开源流产,真的对你影响很大吗?
  • Git初体验
  • isset在php5.6-和php7.0+的一些差异
  • Mac 鼠须管 Rime 输入法 安装五笔输入法 教程
  • nfs客户端进程变D,延伸linux的lock
  • oschina
  • python大佬养成计划----difflib模块
  • session共享问题解决方案
  • Spark RDD学习: aggregate函数
  • Vue ES6 Jade Scss Webpack Gulp
  • vuex 学习笔记 01
  • 彻底搞懂浏览器Event-loop
  • 关于extract.autodesk.io的一些说明
  • 力扣(LeetCode)21
  • 漫谈开发设计中的一些“原则”及“设计哲学”
  • 微服务入门【系列视频课程】
  • 微信小程序开发问题汇总
  • 我有几个粽子,和一个故事
  • 06-01 点餐小程序前台界面搭建
  • #pragma 指令
  • #微信小程序:微信小程序常见的配置传值
  • $con= MySQL有关填空题_2015年计算机二级考试《MySQL》提高练习题(10)
  • (3)(3.2) MAVLink2数据包签名(安全)
  • (31)对象的克隆
  • (C#)Windows Shell 外壳编程系列9 - QueryInfo 扩展提示
  • (poj1.2.1)1970(筛选法模拟)
  • (理论篇)httpmoudle和httphandler一览
  • (论文阅读26/100)Weakly-supervised learning with convolutional neural networks
  • (求助)用傲游上csdn博客时标签栏和网址栏一直显示袁萌 的头像
  • (一)为什么要选择C++
  • ... fatal error LINK1120:1个无法解析的外部命令 的解决办法
  • ..回顾17,展望18
  • .net oracle 连接超时_Mysql连接数据库异常汇总【必收藏】
  • .NET Standard 的管理策略
  • .Net 基于.Net8开发的一个Asp.Net Core Webapi小型易用框架
  • .NetCore+vue3上传图片 Multipart body length limit 16384 exceeded.
  • .NetCore部署微服务(二)
  • .NET国产化改造探索(三)、银河麒麟安装.NET 8环境