- 浏览: 56244 次
- 性别:
- 来自: 上海
最新评论
-
冲锋陷阵:
这一个办法还是不行。。。
文件编码格式转换 -
jxd1976:
下面没了?
Hessian2序列化 -
ccj:
使用Gwt-SL整合效果很好.
GWT和AOP -
gwbasic:
有新版本了,请参照论坛中的<<gwt spring ...
GWT和AOP -
li_tieyang:
ServerSerializationStreamReader ...
GWT和AOP
unit Hessian2Output; { title: hessian 2.0 序列化 author: Xiao Chun email: cnxiaochun#gmail.com version: draft reference: http://hessian.caucho.com/ } interface uses Classes; const BUFFER_SIZE = 4096; INT_DIRECT_MIN = -$10; INT_DIRECT_MAX = $2F; INT_ZERO = $90; INT_BYTE_MIN = -$800; INT_BYTE_MAX = $7FF; INT_BYTE_ZERO = $C8; INT_SHORT_MIN = -$40000; INT_SHORT_MAX = $3FFFF; INT_SHORT_ZERO = $D4; LONG_DIRECT_MIN = -$08; LONG_DIRECT_MAX = $0F; LONG_ZERO = $E0; LONG_BYTE_MIN = -$800; LONG_BYTE_MAX = $7FF; LONG_BYTE_ZERO = $F8; LONG_SHORT_MIN = -$40000; LONG_SHORT_MAX = $3FFFF; LONG_SHORT_ZERO = $3C; LONG_INT_MIN = -$7FFFFFFF - 1; LONG_INT_MAX = $7FFFFFFF; LONG_INT_ZERO = $77; STRING_DIRECT_MAX = $1F; STRING_DIRECT = $00; BYTES_DIRECT_MAX = $0F; BYTES_DIRECT = $20; DOUBLE_ZERO = $67; DOUBLE_ONE = $68; DOUBLE_BYTE = $69; DOUBLE_SHORT = $6A; DOUBLE_FLOAT = $6B; LENGTH_BYTE = $6E; LIST_FIXED = $76; // 'v' REF_BYTE = $4A; REF_SHORT = $4B; TYPE_REF = $75; type THessian2Output = class(TObject) private FBuffer: array[0..BUFFER_SIZE - 1] of Byte; FOffset: integer; FStream: TStream; FFreeStreamOnDestroy: boolean; _typeRefs: TStringList; procedure PrintString(const AValue: WideString; AOffset, ACount: integer); procedure WriteType(const AType: WideString); procedure _WriteString(const AValue: WideString; AOffset, ACount: integer); public constructor Create(AStream: TStream); destructor Destroy; override; public procedure StartCall(const AMethodName: WideString); procedure CompleteCall; procedure Flush; procedure WriteInt(AValue: integer); procedure WriteLong(AValue: Int64); procedure WriteDouble(AValue: Double); procedure WriteBoolean(AValue: boolean); procedure WriteNull; procedure WriteString(const AValue: WideString); procedure WriteUTCDate(AValue: TDateTime); procedure WriteBytes(ASourceStream: TStream); overload; procedure WriteBytes(ASourceStream: TStream; AOffset, ACount: integer); overload; procedure WriteMapBegin; overload; procedure WriteMapBegin(const AType: WideString); overload; procedure WriteMapEnd; function WriteListBegin(ALength: integer; const AType: WideString): boolean; overload; function WriteListBegin(ALength: integer): boolean; overload; procedure WriteListEnd; end; implementation uses JavaDate; constructor THessian2Output.Create(AStream: TStream); begin inherited Create; FOffset := 0; if Assigned(AStream) then begin FFreeStreamOnDestroy := false; FStream := AStream; end else begin FFreeStreamOnDestroy := true; FStream := TMemoryStream.Create; end; end; destructor THessian2Output.Destroy; begin if FFreeStreamOnDestroy then FStream.Free; if Assigned(_typeRefs) then _typeRefs.Free; inherited; end; procedure THessian2Output.StartCall(const AMethodName: WideString); var Len: Integer; begin if BUFFER_SIZE < FOffset + 16 then Flush; FBuffer[FOffset] := Byte('c'); Inc(FOffset); FBuffer[FOffset] := Byte(2); Inc(FOffset); FBuffer[FOffset] := Byte(0); Inc(FOffset); FBuffer[FOffset] := Byte('m'); Inc(FOffset); Len := Length(AMethodName); FBuffer[FOffset] := Byte(len shr 8 ); Inc(FOffset); FBuffer[FOffset] := Byte(len); Inc(FOffset); PrintString(AMethodName, 0, Len); end; procedure THessian2Output.CompleteCall; begin if BUFFER_SIZE < FOffset + 16 then Flush; FBuffer[FOffset] := Byte('z'); Inc(FOffset); end; procedure THessian2Output.WriteInt(AValue: integer); begin if BUFFER_SIZE < FOffset + 16 then Flush; if (INT_DIRECT_MIN <= AValue) and (AValue <= INT_DIRECT_MAX) then begin FBuffer[FOffset] := Byte(AValue + INT_ZERO); Inc(FOffset); end else if (INT_BYTE_MIN <= AValue) and (AValue <= INT_BYTE_MAX) then begin FBuffer[FOffset] := Byte(INT_BYTE_ZERO + (AValue shr 8 )); Inc(FOffset); FBuffer[FOffset] := Byte(AValue); Inc(FOffset); end else if (INT_SHORT_MIN <= AValue) and (AValue <= INT_SHORT_MAX) then begin FBuffer[FOffset] := Byte(INT_SHORT_ZERO + (AValue shr 16 )); Inc(FOffset); FBuffer[FOffset] := Byte(AValue shr 8 ); Inc(FOffset); FBuffer[FOffset] := Byte(AValue); Inc(FOffset); end else begin FBuffer[FOffset] := Byte('I'); Inc(FOffset); FBuffer[FOffset] := Byte(AValue shr 24); Inc(FOffset); FBuffer[FOffset] := Byte(AValue shr 16); Inc(FOffset); FBuffer[FOffset] := Byte(AValue shr 8 ); Inc(FOffset); FBuffer[FOffset] := Byte(AValue); Inc(FOffset); end end; procedure THessian2Output.WriteLong(AValue: int64); begin if BUFFER_SIZE < FOffset + 16 then Flush; if (LONG_DIRECT_MIN <= AValue) and (AValue <= LONG_DIRECT_MAX) then begin FBuffer[FOffset] := Byte(AValue + LONG_ZERO); Inc(FOffset); end else if (LONG_BYTE_MIN <= AValue) and (AValue <= LONG_BYTE_MAX) then begin FBuffer[FOffset] := Byte(LONG_BYTE_ZERO + (AValue shr 8 )); Inc(FOffset); FBuffer[FOffset] := Byte(AValue); Inc(FOffset); end else if (LONG_SHORT_MIN <= AValue) and (AValue <= LONG_SHORT_MAX) then begin FBuffer[FOffset] := Byte(LONG_SHORT_ZERO + (AValue shr 16)); Inc(FOffset); FBuffer[FOffset] := Byte(AValue shr 8 ); Inc(FOffset); FBuffer[FOffset] := Byte(AValue); Inc(FOffset); end else if (LONG_INT_MIN <= AValue) and (AValue <= LONG_INT_MAX) then begin FBuffer[FOffset] := Byte(LONG_INT_ZERO); Inc(FOffset); FBuffer[FOffset] := Byte(AValue shr 24); Inc(FOffset); FBuffer[FOffset] := Byte(AValue shr 16); Inc(FOffset); FBuffer[FOffset] := Byte(AValue shr 8 ); Inc(FOffset); FBuffer[FOffset] := Byte(AValue); Inc(FOffset); end else begin FBuffer[FOffset] := Byte('L'); Inc(FOffset); FBuffer[FOffset] := Byte(AValue shr 56); Inc(FOffset); FBuffer[FOffset] := Byte(AValue shr 48); Inc(FOffset); FBuffer[FOffset] := Byte(AValue shr 40); Inc(FOffset); FBuffer[FOffset] := Byte(AValue shr 32); Inc(FOffset); FBuffer[FOffset] := Byte(AValue shr 24); Inc(FOffset); FBuffer[FOffset] := Byte(AValue shr 16); Inc(FOffset); FBuffer[FOffset] := Byte(AValue shr 8 ); Inc(FOffset); FBuffer[FOffset] := Byte(AValue); Inc(FOffset); end end; procedure THessian2Output.WriteDouble(AValue: Double); var intValue: integer; longValue: int64; floatValue: single; begin if BUFFER_SIZE < FOffset + 16 then Flush; if Int(AValue) = AValue then begin // 只有整数部分 intValue := Round(AValue); if intValue = 0 then begin FBuffer[FOffset] := Byte(DOUBLE_ZERO); Inc(FOffset); exit; end else if intValue = 1 then begin FBuffer[FOffset] := Byte(DOUBLE_ONE); Inc(FOffset); exit; end else if (-$80 <= intValue) and (intValue < $80) then begin FBuffer[FOffset] := Byte(DOUBLE_BYTE); Inc(FOffset); FBuffer[FOffset] := Byte(intValue); Inc(FOffset); exit; end else if ($8000 <= intValue) and (intValue < $8000) then begin FBuffer[FOffset] := Byte(DOUBLE_SHORT); Inc(FOffset); FBuffer[FOffset] := Byte(intValue shr 8 ); Inc(FOffset); FBuffer[FOffset] := Byte(intValue); Inc(FOffset); exit; end; end; floatValue := AValue; if floatValue = AValue then begin FBuffer[FOffset] := Byte(DOUBLE_FLOAT); Inc(FOffset); intValue := PInteger(@floatValue)^; FBuffer[FOffset] := Byte(intValue shr 24); Inc(FOffset); FBuffer[FOffset] := Byte(intValue shr 16); Inc(FOffset); FBuffer[FOffset] := Byte(intValue shr 8 ); Inc(FOffset); FBuffer[FOffset] := Byte(intValue); Inc(FOffset); exit; end; FBuffer[FOffset] := Byte('D'); Inc(FOffset); longValue := PInt64(@AValue)^; FBuffer[FOffset] := Byte(longValue shr 56); Inc(FOffset); FBuffer[FOffset] := Byte(longValue shr 48); Inc(FOffset); FBuffer[FOffset] := Byte(longValue shr 40); Inc(FOffset); FBuffer[FOffset] := Byte(longValue shr 32); Inc(FOffset); FBuffer[FOffset] := Byte(longValue shr 24); Inc(FOffset); FBuffer[FOffset] := Byte(longValue shr 16); Inc(FOffset); FBuffer[FOffset] := Byte(longValue shr 8 ); Inc(FOffset); FBuffer[FOffset] := Byte(longValue); Inc(FOffset); end; procedure THessian2Output.WriteBoolean(AValue: boolean); begin if BUFFER_SIZE < FOffset + 16 then Flush; if AValue then begin FBuffer[FOffset] := Byte('T'); Inc(FOffset); end else begin FBuffer[FOffset] := Byte('F'); Inc(FOffset); end end; procedure THessian2Output.WriteString(const AValue: WideString); begin _WriteString(AValue, 0, Length(AValue)); end; procedure THessian2Output.WriteUTCDate(AValue: TDateTime); var UTCValue: int64; begin UTCValue := DateTimeToJavaDate(AValue); if BUFFER_SIZE < FOffset + 16 then Flush; FBuffer[FOffset] := Byte('d'); Inc(FOffset); FBuffer[FOffset] := Byte(UTCValue shr 56); Inc(FOffset); FBuffer[FOffset] := Byte(UTCValue shr 48); Inc(FOffset); FBuffer[FOffset] := Byte(UTCValue shr 40); Inc(FOffset); FBuffer[FOffset] := Byte(UTCValue shr 32); Inc(FOffset); FBuffer[FOffset] := Byte(UTCValue shr 24); Inc(FOffset); FBuffer[FOffset] := Byte(UTCValue shr 16); Inc(FOffset); FBuffer[FOffset] := Byte(UTCValue shr 8 ); Inc(FOffset); FBuffer[FOffset] := Byte(UTCValue); Inc(FOffset); end; procedure THessian2Output.WriteNull; begin if BUFFER_SIZE < FOffset + 16 then Flush; FBuffer[FOffset] := Byte('N'); Inc(FOffset); end; procedure THessian2Output.WriteBytes(ASourceStream: TStream); begin if ASourceStream = nil then begin WriteNull; end else begin WriteBytes(ASourceStream, 0, ASourceStream.Size); end; end; procedure THessian2Output.WriteBytes(ASourceStream: TStream; AOffset, ACount: integer); var sublen: integer; N: integer; begin if ASourceStream = nil then begin WriteNull; end else begin if AOffset > 0 then begin ASourceStream.Position := AOffset; end else begin ASourceStream.Position := 0; end; if BUFFER_SIZE < FOffset + 16 then Flush; while ACount > $8000 do begin FBuffer[FOffset] := Byte('b'); Inc(FOffset); FBuffer[FOffset] := Byte($8000 shr 8 ); Inc(FOffset); FBuffer[FOffset] := Byte($8000); Inc(FOffset); sublen := $8000; while sublen > 0 do begin if sublen > (BUFFER_SIZE - FOffset) then N := BUFFER_SIZE - FOffset else N := sublen; ASourceStream.ReadBuffer(FBuffer, N); Inc(FOffset, N); // Flush FStream.WriteBuffer(FBuffer, FOffset); FOffset := 0; Dec(sublen, N); end; ACount := ACount - $8000; //AOffset := AOffset + $80000; end; if ACount < $10 then begin FBuffer[FOffset] := Byte(BYTES_DIRECT + ACount); Inc(FOffset); end else begin FBuffer[FOffset] := Byte('B'); Inc(FOffset); FBuffer[FOffset] := Byte(ACount shr 8 ); Inc(FOffset); FBuffer[FOffset] := Byte(ACount); Inc(FOffset); end; while ACount > 0 do begin if ACount > (BUFFER_SIZE - FOffset) then N := BUFFER_SIZE - FOffset else N := ACount; ASourceStream.ReadBuffer(FBuffer, N); Inc(FOffset, N); // Flush FStream.WriteBuffer(FBuffer, FOffset); FOffset := 0; Dec(ACount, N); end; end end; procedure THessian2Output.WriteMapBegin; begin WriteMapBegin(''); end; procedure THessian2Output.WriteMapBegin(const AType: WideString); begin if BUFFER_SIZE < FOffset + 16 then Flush; FBuffer[FOffset] := Byte('M'); Inc(FOffset); WriteType(AType); end; procedure THessian2Output.WriteMapEnd; begin if BUFFER_SIZE < FOffset + 16 then Flush; FBuffer[FOffset] := Byte('z'); Inc(FOffset); end; function THessian2Output.WriteListBegin(ALength: integer): boolean; begin result := WriteListBegin(ALength, ''); end; function THessian2Output.WriteListBegin(ALength: integer; const AType: WideString): boolean; var refV: integer; begin if _typeRefs <> nil then begin refV := _typeRefs.IndexOf(AType); if refV >= 0 then begin refV := Integer(_typeRefs.Objects[refV]); if BUFFER_SIZE < FOffset + 16 then Flush; FBuffer[FOffset] := Byte(LIST_FIXED); Inc(FOffset); WriteInt(refV); WriteInt(ALength); result := false; exit; end end; if BUFFER_SIZE < FOffset + 16 then Flush; FBuffer[FOffset] := Byte('V'); Inc(FOffset); WriteType(AType); if BUFFER_SIZE < FOffset + 16 then Flush; if ALength < 0 then begin end else if ALength < $100 then begin FBuffer[FOffset] := Byte(LENGTH_BYTE); Inc(FOffset); FBuffer[FOffset] := Byte(ALength); Inc(FOffset); end else begin FBuffer[FOffset] := Byte('l'); Inc(FOffset); FBuffer[FOffset] := Byte(ALength shr 24); Inc(FOffset); FBuffer[FOffset] := Byte(ALength shr 16); Inc(FOffset); FBuffer[FOffset] := Byte(ALength shr 8 ); Inc(FOffset); FBuffer[FOffset] := Byte(ALength); Inc(FOffset); end; result := True; end; procedure THessian2Output.WriteListEnd; begin if BUFFER_SIZE < FOffset + 16 then Flush; FBuffer[FOffset] := Byte('z'); Inc(FOffset); end; procedure THessian2Output._WriteString(const AValue: WideString; AOffset, ACount: integer); var sublen: integer; tail: integer; begin while ACount > $8000 do begin if BUFFER_SIZE < FOffset + 16 then Flush; sublen := $8000; // chunk can't end in high surrogate tail := Integer(AValue[AOffset + sublen - 1]); if ($D800 <= tail) and (tail <= $DBFF) then dec(sublen); FBuffer[FOffset] := Byte('s'); Inc(FOffset); FBuffer[FOffset] := Byte(sublen shr 8 ); Inc(FOffset); FBuffer[FOffset] := Byte(sublen); Inc(FOffset); PrintString(AValue, AOffset, sublen); ACount := ACount - sublen; AOffset := AOffset + sublen; end; if BUFFER_SIZE < FOffset + 16 then Flush; if ACount <= STRING_DIRECT_MAX then begin FBuffer[FOffset] := Byte(STRING_DIRECT + ACount); Inc(FOffset); end else begin FBuffer[FOffset] := Byte('S'); Inc(FOffset); FBuffer[FOffset] := Byte(ACount shr 8 ); Inc(FOffset); FBuffer[FOffset] := Byte(ACount); Inc(FOffset); end; PrintString(AValue, AOffset, ACount); end; procedure THessian2Output.WriteType(const AType: WideString); var Len: integer; typeRefV: integer; begin Len := Length(AType); if Len = 0 then exit; if _typeRefs = nil then begin _typeRefs := TStringList.Create; end; typeRefV := _typeRefs.IndexOf(AType); if typeRefV >= 0 then begin typeRefV := Integer(_typeRefs.Objects[typeRefV]); if BUFFER_SIZE < FOffset + 16 then Flush; FBuffer[FOffset] := Byte(TYPE_REF); Inc(FOffset); writeInt(typeRefV); end else begin _typeRefs.AddObject(AType, TObject(_typeRefs.Count)); if BUFFER_SIZE < FOffset + 16 then Flush; FBuffer[FOffset] := Byte('t'); Inc(FOffset); FBuffer[FOffset] := Byte(Len shr 8 ); Inc(FOffset); FBuffer[FOffset] := Byte(Len); Inc(FOffset); PrintString(AType, 0, Len); end end; procedure THessian2Output.PrintString(const AValue: WideString; AOffset, ACount: integer); var I: integer; ch: integer; begin for i := 1 to ACount do begin if BUFFER_SIZE < FOffset + 16 then Flush; // encoded as UTF-8 ch := Integer(AValue[i + AOffset]); if ch < $80 then begin FBuffer[FOffset] := Byte(ch); Inc(FOffset); end else if ch < $800 then begin FBuffer[FOffset] := Byte($C0 + ((ch shr 6) and $1F)); Inc(FOffset); FBuffer[FOffset] := Byte($80 + (ch and $3F)); Inc(FOffset); end else begin FBuffer[FOffset] := Byte($E0 + ((ch shr 12) and $F)); Inc(FOffset); FBuffer[FOffset] := Byte($80 + ((ch shr 6) and $3F)); Inc(FOffset); FBuffer[FOffset] := Byte($80 + (ch and $3F)); Inc(FOffset); end end end; procedure THessian2Output.Flush; var offset: integer; begin offset := FOffset; if offset > 0 then begin FOffset := 0; FStream.WriteBuffer(FBuffer, offset); end end; end.
评论
5 楼
jxd1976
2008-08-06
下面没了?
4 楼
neo
2007-10-26
不错,期待早点出反序列化的Unit啊
3 楼
tiyi
2007-10-16
超爱Delphi。
还要做反序列化的。
还要做反序列化的。
2 楼
lgx522
2007-10-12
有没有反序列化的?
如果能够反序列化,则可Java+Hessian+Delphi,相当完美的组合。
如果能够反序列化,则可Java+Hessian+Delphi,相当完美的组合。
1 楼
liwenjun
2007-10-10
我正在找delphi做hessian客户端方面的资料,感谢lz的无么提供。
能不能给些范例?12
能不能给些范例?12
相关推荐
例如,服务器端可以使用Hessian序列化响应数据,客户端则通过反序列化接收到的二进制流来获取对象。这使得通信过程更为高效,尤其在数据量较大时,相比于文本格式,二进制格式能显著减少网络传输时间。 Hessian工具...
【S25-Hessian反序列化1】是一个关于Java中Hessian序列化库的讨论,主要涉及Hessian与原生Java序列化的差异以及在Spring框架中的应用。Hessian是一种二进制序列化协议,旨在提高远程过程调用(RPC)的效率。与原生Java...
- 首先,Hessian序列化器会遍历Java对象的所有字段,对每个字段进行处理。 - 对于基本类型,如int、boolean、double等,Hessian有专门的编码方式,直接将其转换为字节。 - 对于复杂类型如对象和数组,Hessian会...
《Hessian 2.0序列化协议规范》 在分布式计算和网络通信中,数据的序列化和反序列化是至关重要的环节。Hessian 2.0是一种高效的二进制序列化协议,它旨在减少网络传输的数据量,提高数据交换的效率。本文将详细介绍...
《Hessian序列化规范详解》 在分布式系统中,数据传输是不可或缺的一部分,而序列化与反序列化作为数据传输的基础,扮演着至关重要的角色。Hessian,作为一种高效的二进制序列化协议,由Caucho公司开发,广泛应用于...
### Nacos JRaft Hessian 反序列化 RCE 分析 #### 一、背景介绍 Nacos 是阿里巴巴开源的一款易于构建云原生应用的动态服务发现、配置管理和服务管理平台。JRafT 是 SOFAStack 微服务平台中的一个分布式一致性组件...
Java序列化和Hessian序列化的差异 Java序列化和Hessian序列化是两种常用的序列化机制,它们都可以将对象转换为字节流,以便在网络上传输。但是,两者之间有着很大的差异,今天我们就来比较一下它们的实现机制和特点...
removal RCE、Hessian 反序列化、Yaml反序列化、密码解密、部分常用敏感路径(漏洞更新截止2024.9.12)
Hessian的目标是提供一种快速、简洁的数据序列化和远程方法调用(RPC)机制。在这个简单的demo中,我们将探讨Hessian的核心概念,以及如何在实际应用中使用它。 首先,我们需要理解什么是数据序列化。数据序列化是...
2. **简单类型支持**:Hessian支持基本的Java数据类型,如整型、浮点型、字符串、日期等,并且可以序列化和反序列化复杂对象。 3. **流式传输**:Hessian协议允许数据分块传输,这意味着服务端可以立即响应部分结果...
4. **序列化**:由于Hessian是基于二进制的,因此传输的对象需要实现`Serializable`接口,以确保它们能被正确序列化和反序列化。 5. **客户端调用**:客户端通过生成服务接口的代理对象来调用服务端的方法,这些...
- **二进制序列化**:Hessian的二进制序列化机制将Java对象转换为紧凑的二进制形式,这种方式不仅比XML等文本格式更节省空间,而且提高了序列化的速度。 - **远程调用模型**:Hessian提供了客户端和服务端两部分组件...
1. **序列化**:Dubbo 默认使用 Hessian 2 序列化库,同时支持 Java 的 Serializable 机制,并提供了更高效的序列化实现。 - **Hessian 2**:一种高效的二进制格式,适合网络传输。 - **Java Serializable**:Java...
服务端使用Hessian序列化`Person`对象,客户端则接收这个二进制流并反序列化为`Person`对象。这可以通过Hessian提供的库来实现,例如在Java中,我们可以使用Caucho的Hessian库。 在实际应用中,Hessian常用于微服务...
hessian.jar,Hessian的序列化输出 ,
Dubbox支持服务的注册与发现,动态配置,监控,负载均衡,容错,以及多种序列化方式,如Hessian2、Fast serialization等。这些特性使得Dubbox成为分布式系统中的关键组件,能够帮助开发者构建高可用、高性能的服务...
同时,它也支持多种序列化方式,如Java自带的Java序列化、Hessian2序列化等,以适应不同的性能和兼容性需求。 4. **负载均衡**:Dubbo提供了多种负载均衡策略,如Random、RoundRobin、LeastActive等,可以根据实际...