接着说Spring包装过的Hessian怎么来Hack。
刚开始我以为只要改了hessian的源码,就可以了。其实不然,因为Spring通过了几层包装,让你不能得不到request对象。
Spring里边hessian的入口是HessianServiceExporter这个类,主要方法有两个
- public void prepare() {
- HessianSkeleton skeleton = null;
- try {
- try {
- // Try Hessian 3.x (with service interface argument).
- Constructor ctor = HessianSkeleton.class.getConstructor(new Class[] {Object.class, Class.class});
- checkService();
- checkServiceInterface();
- skeleton = (HessianSkeleton)
- ctor.newInstance(new Object[] {getProxyForService(), getServiceInterface()});
- }
- catch (NoSuchMethodException ex) {
- // Fall back to Hessian 2.x (without service interface argument).
- Constructor ctor = HessianSkeleton.class.getConstructor(new Class[] {Object.class});
- skeleton = (HessianSkeleton) ctor.newInstance(new Object[] {getProxyForService()});
- }
- }
- catch (Throwable ex) {
- throw new BeanInitializationException("Hessian skeleton initialization failed", ex);
- }
- if (hessian2Available) {
- // Hessian 2 (version 3.0.20+).
- this.skeletonInvoker = new Hessian2SkeletonInvoker(skeleton, this.serializerFactory);
- }
- else {
- // Hessian 1 (version 3.0.19-).
- this.skeletonInvoker = new Hessian1SkeletonInvoker(skeleton, this.serializerFactory);
- }
- }
- /**
- * Processes the incoming Hessian request and creates a Hessian response.
- */
- public void handleRequest(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- Assert.notNull(this.skeletonInvoker, "HessianServiceExporter has not been initialized");
- if (!"POST".equals(request.getMethod())) {
- throw new HttpRequestMethodNotSupportedException(
- "POST", "HessianServiceExporter only supports POST requests");
- }
- try {
- this.skeletonInvoker.invoke(request.getInputStream(), response.getOutputStream());
- }
- catch (Throwable ex) {
- throw new NestedServletException("Hessian skeleton invocation failed", ex);
- }finally{
- ServiceContext.end();
- }
- }
prepare()方法是在Spring环境加载的时候执行的,用来初始化Hessian的HessianSkeleton并包装成Spring自己的Hessian2SkeletonInvoker。
handleRequest()方法是每次远程调用的入口,里边的这个方法执行后续hessian的解析流程
- this.skeletonInvoker.invoke(request.getInputStream(), response.getOutputStream());
skeletonInvoker也就是prepare里初始化的Hessian2SkeletonInvoker,跟进去看看先
- class Hessian2SkeletonInvoker extends HessianSkeletonInvoker {
- public Hessian2SkeletonInvoker(HessianSkeleton skeleton, SerializerFactory serializerFactory) {
- super(skeleton, serializerFactory);
- }
- public void invoke(InputStream inputStream, OutputStream outputStream) throws Throwable {
- Hessian2Input in = new Hessian2Input(inputStream);
- if (this.serializerFactory != null) {
- in.setSerializerFactory(this.serializerFactory);
- }
- int code = in.read();
- if (code != 'c') {
- throw new IOException("expected 'c' in hessian input at " + code);
- }
- AbstractHessianOutput out = null;
- int major = in.read();
- int minor = in.read();
- if (major >= 2) {
- out = new Hessian2Output(outputStream);
- }
- else {
- out = new HessianOutput(outputStream);
- }
- if (this.serializerFactory != null) {
- out.setSerializerFactory(this.serializerFactory);
- }
- this.skeleton.invoke(in, out);
- }
- }
Hessian2SkeletonInvoker的构造函数进行父类的初始化,也就是初始化了最重要的HessianSkeleton
再看invoke()方法,是不是有点眼熟,对了,这就是hessian源代码里边的以部分代码,用来包装输入输入流为Hessian自己的Hessian2Input 等,然后判断开头的字节是否正确,以及确定HessianOutput的版本。这些都是解析输入流里边的字节标志位来实现的。 在方法的最后调用了
- this.skeleton.invoke(in, out);
,也就是把控制权交给了Hessian来处理,这样后续的工作就是Hessian中完成。但是这样就ok了吗?慢着,我们是不是漏了点什么? 对,那个ServiceContext上下文。因为Hessian是在自己的入口Servlet中生成上下文的,但是Spring并没有生成这个东西。所以,我在这里自己生成了它,唯一一个能够生成的地方就在Spring的HessianServiceExporter的handleRequest()里边,只有在这里才有request对象。因此我把handleRequest()方法中加了一句ServiceContext.begin(request, null, null);然后在finally里边加了一句ServiceContext.end();
代码如下:
- public void handleRequest(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- Assert.notNull(this.skeletonInvoker, "HessianServiceExporter has not been initialized");
- ServiceContext.begin(request, null, null);
- if (!"POST".equals(request.getMethod())) {
- throw new HttpRequestMethodNotSupportedException(
- "POST", "HessianServiceExporter only supports POST requests");
- }
- try {
- this.skeletonInvoker.invoke(request.getInputStream(), response.getOutputStream());
- }
- catch (Throwable ex) {
- throw new NestedServletException("Hessian skeleton invocation failed", ex);
- }finally{
- ServiceContext.end();
- }
- }
ServiceContext.begin()方法生成一个ThreadLocal对象,ServiceContext.end()则释放它里边的上下文。
加了这个地方,就可以用上面的hessian源码进行剩余操作了
相关推荐
com.alibaba:hessian-lite:jar:3.2.1-fixed-2 hessian-lite hessian-lite-3.2.1-fixed-2.jar
《Hessian源码分析与Hack:携带远程调用端信息》 Hessian作为一种轻量级的RPC(远程过程调用)框架,因其高效、简洁的二进制协议,被广泛应用于构建Web服务。然而,在实际应用中,有时我们需要获取到远程调用端的IP...
赠送Maven依赖信息文件:hessian-4.0.63.pom; 包含翻译后的API文档:hessian-4.0.63-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:com.caucho:hessian:4.0.63; 标签:hessian、caucho、jar包、java、...
- **配置详解**:文档通常会包含如何配置Hessian服务端和客户端的详细步骤,例如设置服务器端的监听端口,客户端的连接参数等。 - **示例代码**:提供服务端和服务端的代码示例,展示如何创建、注册服务以及如何...
赠送Maven依赖信息文件:hessian-4.0.63.pom; 包含翻译后的API文档:hessian-4.0.63-javadoc-API文档-中文(简体)版.zip; Maven坐标:com.caucho:hessian:4.0.63; 标签:hessian、caucho、jar包、java、中文文档;...
Hessian是一种高效的二进制序列化协议,常用于远程过程调用(RPC)和服务之间的通信。这个压缩包包含了Hessian的多个版本,分别是Hessian3.1.6、Hessian3.2.1以及Hessian4.0.7。每个版本都有其特定的功能改进和优化...
在解压的"**hessian-4.0.51-src**"源码包中,主要包含两个关键文件:"**pom.xml**"和"**src**"。 1. **pom.xml**:这是Maven项目的配置文件,定义了项目依赖、构建过程等信息。通过这个文件,我们可以看到Hessian ...
赠送jar包:hessian-3.3.6.jar 赠送原API文档:hessian-3.3.6-javadoc.jar 赠送源代码:hessian-3.3.6-sources.jar 包含翻译后的API文档:hessian-3.3.6-javadoc-API文档-中文(简体)-英语-对照版.zip 对应Maven...
在IT行业中,远程调用是一种常见的技术,使得客户端可以跨网络调用远程服务器上的方法,就像调用本地方法一样方便。Hessian是Apache项目下的一个轻量级的RPC(Remote Procedure Call,远程过程调用)框架,它提供了...
赠送Maven依赖信息文件:hessian-3.3.6.pom; 包含翻译后的API文档:hessian-3.3.6-javadoc-API文档-中文(简体)版.zip; Maven坐标:com.alipay.sofa:hessian:3.3.6; 标签:sofa、hessian、alipay、jar包、java、...
Hessian远程调用框架是基于Java的轻量级RPC(Remote Procedure Call)解决方案,它允许开发者在分布式系统中实现高效、便捷的跨网络对象方法调用。本教程将引导你入门Hessian,通过一个简单的JAVA demo来理解其工作...
hessian是一个轻量级的Java Remoting方案
Hessian是一种轻量级的二进制Web服务协议,它由Caucho Technology开发,用于提高远程调用的效率和速度。Hessian 4.0.7是该协议的一个版本,提供了一个Java库,允许开发者在Java应用之间进行高效的数据交换。这个版本...
《深入理解Hessian框架:以hessian-4.0.33.jar为例》 Hessian是一种高效的二进制RPC(Remote Procedure Call)协议,由Caucho Technology开发,旨在提供轻量级、高效的远程调用服务。在这个专题中,我们将以hessian...
在服务器端,通过HessianServlet来暴露这个服务,客户端则通过HessianProxyFactory来创建服务代理,从而能够调用远程服务的方法。这种简单设置可以让开发者快速理解Hessian的基本工作原理。 二、Hessian与Spring...
java运行依赖jar包
Spring会自动创建代理对象,使得客户端可以通过这个代理对象调用远程服务的方法,就像调用本地对象一样。 3. **使用源码分析**: Hessian库提供了`HessianProxyFactoryBean`和`HessianServiceExporter`这两个关键...
1. **远程调用**:在Dubbo框架中,Hessian-lite用于实现服务调用的二进制序列化和反序列化,使得远程方法调用(RMI)更加高效。它将Java对象转换为二进制流,通过网络发送,然后在服务端反序列化回原来的对象,降低了...
Hessian二进制Web服务协议(Hessian Binary Web Service Protocol)是一种高效的、轻量级的远程过程调用(RPC)协议,它主要用于提高Web服务之间的通信效率。Hessian由Caucho Technology公司开发,旨在解决XML-RPC在...