- 浏览: 461219 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
syw19901001:
30多条mysql数据库优化方法,千万级数据库记录查询轻松解决 ...
MYSQL的全表扫描,主键索引(聚集索引、第一索引),非主键索引(非聚集索引、第二索引),覆盖索引四种不同查询的分析 -
gaoyuanyuan121:
直接改成root.war,根路径能访问,项目路径也能访问,赞 ...
jetty 中如何设置root app -
freezingsky:
翻出来,再看一次!
AOP 的简单入门 -
Shen.Yiyang:
inter12 写道Shen.Yiyang 写道我说的不是NI ...
ReentrantLock、sync、ReentrantReadWriteLock性能比较 -
inter12:
Shen.Yiyang 写道我说的不是NIO和BIO的区别,而 ...
ReentrantLock、sync、ReentrantReadWriteLock性能比较
Hessian 的字段序列化小记
一背景:
今天线上碰到一个问题,在通过hessian的反序列化的时候失败了。
简单查看了下原因,是因为服务端和客户端依赖的bean包版本不一致导致的。
二 具体分析:
Client --- > commons-entity
Sever --- > commons-entity
做了依赖倒置处理,服务端及客户端都持有服务接口及对象的包。
commons-entity 存在两个版本:服务端版本(新版本)及客户端版本(旧版本)。两个版本之间区别在于对于某个字段的类型做了改变。
下面就分析下不同场景下hessian的处理结果。
1.服务端 字段A:Date 客户端 字段A:Timestamp 反序列化出错
2.服务端 字段A:Timestamp 客户端 字段A:Date 序列化正常
因为Date是Timestamp的父类,故在反序列化时,向上转型是没有问题的。反之向下转型就存在问题。所以1就会出问题,因为1需要将Date转化成Timestamp类型。
结论:在反序列化时,若是客户端对象是服务端对象的父类,那么不会失败。
tip:对于日期类型的对象还是建议定义为long类型。
三 扩展
以上就是我们具体的故障情况,那么扩展的来测试下一下两种情况是否存在问题。
场景一:
服务端 存在字段A 客户端 无字段A 反序列化正常
结论:反序列化时依赖于客户端所持有的对象,对服务传递字节流进行处理的。不是依赖于服务端的对象处理。这样也很容易理解。因为是客户端需要生成对象。
场景二:
服务端 无字段A 客户端 存在字段A 反序列化正常
结论:反序列化是先解析客户端对象,然后拿着该对象的属性到服务端的字节流中查找,若是存在则生成,若是不存在则忽略该属性的设置,设置为默认值。
总结:在客户端反序列化时候,从服务端中取,若是取不到,则不管,设置为默认值。不管服务端属性是否多余客户端,一切以客户端为准。
四 具体实践代码
附一个hessian的简单使用的核心代码:
server: package com.inter12.hessian; import org.mortbay.jetty.Server; import org.mortbay.jetty.servlet.Context; import org.mortbay.jetty.servlet.ServletHolder; import com.inter12.hessian.service.IPersonServiceServlet; /** * Hello world! */ public class App { /** * * URL: http://localhost:8080/IPersonService * @param args * @throws Exception */ public static void main(String[] args) throws Exception { System.out.println("Hello World!"); // 1.启动一个SERVER 并指定端口 Server server = new Server(8080); // 2.设置应用的跟路径为 / 你也可以设置成自己需要的应用名字。例如我这个的应用是/jTest Context context = new Context(server, "/", Context.SESSIONS); // 3.添加servlet. OKServlet就是我们具体处理业务的类! context.addServlet(new ServletHolder(new IPersonServiceServlet()), "/IPersonService"); // 4.启动。收工,这样就搞定了内置 servlet容器! server.start(); } }
IPersonServiceServlet的实现:
public class IPersonServiceServlet extends HessianServlet implements IPersonService { @Override public void service(ServletRequest arg0, ServletResponse arg1) throws IOException, ServletException { super.service(arg0, arg1); } @Override public void hello() { } @Override public IPerson gerPerson() { Person person = new Person(); person.setAge(20); person.setName("joan"); person.setBirthDay(new Timestamp(System.currentTimeMillis())); return person; } }
相关的依赖:
<dependency>
<groupId>org.mortbay.jetty</groupId> <artifactId>jetty</artifactId> <version>6.1H.14</version> </dependency> <dependency> <groupId>com.inter12.hesian</groupId> <artifactId>common-interface</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>hessian</groupId> <artifactId>hessian</artifactId> <version>3.0.1</version> </dependency>
Client:
public class App { public static void main( String[] args ) throws MalformedURLException { // System.out.println( "Hello World!" ); String url = "http://localhost:8080/IPersonService"; HessianProxyFactory factory = new HessianProxyFactory(); IPersonService service = (IPersonService)factory.create(IPersonService.class, url); Person person = (Person)service.gerPerson(); System.out.println(person.show()); } }
相关的依赖:
<dependency> <groupId>hessian</groupId> <artifactId>hessian</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>com.inter12.hesian</groupId> <artifactId>common-interface</artifactId> <version>1.0.0</version> </dependency>
五 写在最后
先占个坑,以后再深挖hessian的协议。
- hessian.zip (18.7 KB)
- 下载次数: 1
评论
java序列化类:JavaSerializer的源码:
private static FieldSerializer getFieldSerializer(Class type){
......
else if (java.util.Date.class.equals(type)
|| java.sql.Date.class.equals(type)
|| java.sql.Timestamp.class.equals(type)
|| java.sql.Time.class.equals(type)) {
return DateFieldSerializer.SER;
}
......
}
其中DateFieldSerializer.SER的源码为:
static class DateFieldSerializer extends FieldSerializer {
static final FieldSerializer SER = new DateFieldSerializer();
void serialize(AbstractHessianOutput out, Object obj, Field field)
throws IOException
{
java.util.Date value = null;
try {
value = (java.util.Date) field.get(obj);
} catch (IllegalAccessException e) {
log.log(Level.FINE, e.toString(), e);
}
if (value == null)
out.writeNull();
else
out.writeUTCDate(value.getTime());
}
}
综上:我理解是java在序列化的时候把时间类型都转化为java.util.Date类型在进行序列化传输。
[/color][/size]
Java反序列化类:JavaDeserializer源码似乎是支持Date-->Timestamp的
static class SqlDateFieldDeserializer extends FieldDeserializer {
.....
java.util.Date date = (java.util.Date) in.readObject();
value = new java.sql.Date(date.getTime());
.....
}
static class SqlTimestampFieldDeserializer extends FieldDeserializer {
.......
java.util.Date date = (java.util.Date) in.readObject();
value = new java.sql.Timestamp(date.getTime());
........
}
[color=red]综上,java反序列化的时候可以把,先构造成java.util.Date类,然后再转化为不同的类型如java.sql.Date和java.sql.Timestamp等等[size=x-small]
薛少,你看看源码,是不是原因还没有找到呀?你那抛出的异常也应该贴出来的。搞了一下午总算有点回复了。为了和你交流也不容易呀!哈哈
java序列化类:JavaSerializer的源码:
private static FieldSerializer getFieldSerializer(Class type){
......
else if (java.util.Date.class.equals(type)
|| java.sql.Date.class.equals(type)
|| java.sql.Timestamp.class.equals(type)
|| java.sql.Time.class.equals(type)) {
return DateFieldSerializer.SER;
}
......
}
其中DateFieldSerializer.SER的源码为:
static class DateFieldSerializer extends FieldSerializer {
static final FieldSerializer SER = new DateFieldSerializer();
void serialize(AbstractHessianOutput out, Object obj, Field field)
throws IOException
{
java.util.Date value = null;
try {
value = (java.util.Date) field.get(obj);
} catch (IllegalAccessException e) {
log.log(Level.FINE, e.toString(), e);
}
if (value == null)
out.writeNull();
else
out.writeUTCDate(value.getTime());
}
}
综上:我理解是java在序列化的时候把时间类型都转化为java.util.Date类型在进行序列化传输。
[/color][/size]
Java反序列化类:JavaDeserializer源码似乎是支持Date-->Timestamp的
static class SqlDateFieldDeserializer extends FieldDeserializer {
.....
java.util.Date date = (java.util.Date) in.readObject();
value = new java.sql.Date(date.getTime());
.....
}
static class SqlTimestampFieldDeserializer extends FieldDeserializer {
.......
java.util.Date date = (java.util.Date) in.readObject();
value = new java.sql.Timestamp(date.getTime());
........
}
[color=red]综上,java反序列化的时候可以把,先构造成java.util.Date类,然后再转化为不同的类型如java.sql.Date和java.sql.Timestamp等等[size=x-small]
薛少,你看看源码,是不是原因还没有找到呀?你那抛出的异常也应该贴出来的。搞了一下午总算有点回复了。为了和你交流也不容易呀!哈哈
java序列化类:JavaSerializer的源码:
private static FieldSerializer getFieldSerializer(Class type){
......
else if (java.util.Date.class.equals(type)
|| java.sql.Date.class.equals(type)
|| java.sql.Timestamp.class.equals(type)
|| java.sql.Time.class.equals(type)) {
return DateFieldSerializer.SER;
}
......
}
其中DateFieldSerializer.SER的源码为:
static class DateFieldSerializer extends FieldSerializer {
static final FieldSerializer SER = new DateFieldSerializer();
void serialize(AbstractHessianOutput out, Object obj, Field field)
throws IOException
{
java.util.Date value = null;
try {
value = (java.util.Date) field.get(obj);
} catch (IllegalAccessException e) {
log.log(Level.FINE, e.toString(), e);
}
if (value == null)
out.writeNull();
else
out.writeUTCDate(value.getTime());
}
}
综上:我理解是java在序列化的时候把时间类型都转化为java.util.Date类型在进行序列化传输。
Java反序列化类:JavaDeserializer源码似乎是支持Date-->Timestamp的
static class SqlDateFieldDeserializer extends FieldDeserializer {
.....
java.util.Date date = (java.util.Date) in.readObject();
value = new java.sql.Date(date.getTime());
.....
}
static class SqlTimestampFieldDeserializer extends FieldDeserializer {
.......
java.util.Date date = (java.util.Date) in.readObject();
value = new java.sql.Timestamp(date.getTime());
........
}
综上,java反序列化的时候可以把,先构造成java.util.Date类,然后再转化为不同的类型如java.sql.Date和java.sql.Timestamp等等
薛少,你看看源码,是不是原因还没有找到呀?你那抛出的异常也应该贴出来的。搞了一下午总算有点回复了。为了和你交流也不容易呀!哈哈
发表评论
-
AOP 的简单入门
2012-09-08 18:01 4409AOP 的简单入门 自己也算是从业多年,对于 ... -
lucene之第一次亲密接触
2011-12-12 20:30 26111.最近想学lucene ,就去下了最新的3.5版本。发 ... -
struts2学习笔记4
2010-08-02 10:38 9943.所有定义的其他命名空间 是否真是如此呢? ... -
struts2---学习笔记3
2010-08-02 10:38 995<--------------------------- ... -
struts2---学习笔记2
2010-08-02 10:36 1085这里我碰到了一个问题,如果我们简单的将所有的jsp放在/W ... -
struts2---学习笔记1
2010-08-02 10:35 990相信学过一个框架的人在学习另一个框架时会非常的快,因为框架的学 ... -
struts1.x--学习笔记五
2010-08-02 10:33 980一 implict Action which in strut ... -
struts1.x--学习笔记四
2010-08-02 10:32 10465. 显示错误的两种方式 5 ... -
struts1.x--学习笔记三
2010-08-02 10:31 923一.Action ActionForm的三个设计原则 1. ... -
struts1.x--学习笔记二
2010-08-02 10:29 1250step3. 在ActionForm 中,我们需要有表单中提 ... -
struts1.x--学习笔记一
2010-08-02 10:29 927... -
quartz与spring配置
2010-07-30 17:40 1150<!-- 实现规则服务实时加载的定时服务配置文件 --& ... -
spring--AOP简单解析
2010-07-30 17:35 1185SPRING总结 一:IOC 实现IOC的方式有四种 ...
相关推荐
本文将深入探讨Hessian框架的基础知识,它是一个高效的二进制序列化协议,广泛应用于Java和.NET之间跨语言通信。通过学习Hessian,我们可以更有效地处理数据传输,提高应用性能。 首先,让我们理解什么是序列化。...
【S25-Hessian反序列化1】是一个关于Java中Hessian序列化库的讨论,主要涉及Hessian与原生Java序列化的差异以及在Spring框架中的应用。Hessian是一种二进制序列化协议,旨在提高远程过程调用(RPC)的效率。与原生Java...
《Hessian 2.0序列化协议规范》 在分布式计算和网络通信中,数据的序列化和反序列化是至关重要的环节。Hessian 2.0是一种高效的二进制序列化协议,它旨在减少网络传输的数据量,提高数据交换的效率。本文将详细介绍...
### Nacos JRaft Hessian 反序列化 RCE 分析 #### 一、背景介绍 Nacos 是阿里巴巴开源的一款易于构建云原生应用的动态服务发现、配置管理和服务管理平台。JRafT 是 SOFAStack 微服务平台中的一个分布式一致性组件...
《Hessian序列化规范详解》 在分布式系统中,数据传输是不可或缺的一部分,而序列化与反序列化作为数据传输的基础,扮演着至关重要的角色。Hessian,作为一种高效的二进制序列化协议,由Caucho公司开发,广泛应用于...
removal RCE、Hessian 反序列化、Yaml反序列化、密码解密、部分常用敏感路径(漏洞更新截止2024.9.12)
Java序列化和Hessian序列化的差异 Java序列化和Hessian序列化是两种常用的序列化机制,它们都可以将对象转换为字节流,以便在网络上传输。但是,两者之间有着很大的差异,今天我们就来比较一下它们的实现机制和特点...
hessian.jar,Hessian的序列化输出 ,
a --args gadget入参,多个参数使用多次该命令传入,例-a -a Calc-p --protocol [dubbo|http] 通讯协议名称,默认缺省dubbo-s --serialization [hessian|java] 序列化类型,默认缺省hessian-t --target 目标,例:...
默认就是⾛ dubbo 协议,单⼀⻓连接,进⾏的是 NIO 异步通信,基于 hessian 作为序列化协议。使⽤的场景是:传输数据量⼩ (每次请求在 100kb 以内),但是并发量很⾼。 为了要⽀持⾼并发场景,⼀般是服务提供者就⼏...
2. **简单类型支持**:Hessian支持基本的Java数据类型,如整型、浮点型、字符串、日期等,并且可以序列化和反序列化复杂对象。 3. **流式传输**:Hessian协议允许数据分块传输,这意味着服务端可以立即响应部分结果...
为了能够通过Hessian进行序列化和反序列化,实体类需要遵循特定的规则,例如字段类型要简单,避免复杂的嵌套结构。 3. **服务发布**: - 在服务器端,需要将实现类绑定到一个特定的URL,以便客户端可以通过该URL...
这样,客户端通过网络发送一个Hessian序列化的请求,服务端接收后反序列化为本地对象,然后执行相应的操作,再序列化结果返回给客户端。 在实际应用中,Hessian主要应用于以下场景: 1. **分布式服务调用**:通过...
在Java端定义的类可以通过Hessian的`Hessian2Output`进行序列化,C#端的类则需要通过HessianNet的解码器来反序列化。 至于"List"和"Map",它们在Hessian中也有特别的处理方式。Hessian可以序列化和反序列化List和...
通常情况下,如果一个类中的某些字段不需要在网络上传输或者不需要持久化,可以通过`transient`关键字来标记这些字段,使其不在序列化的过程中被处理。 #### 哪些对象需要序列化 决定是否需要序列化一个对象主要...
这意味着 Nacos 使用 Hessian 来序列化和反序列化对象,但并没有正确地设置白名单来限制哪些类可以被反序列化。这为攻击者提供了利用的机会,通过构造恶意的序列化数据包,可以在目标系统上执行任意代码。 #### ...
Hessian的目标是提供一种快速、简洁的数据序列化和远程方法调用(RPC)机制。在这个简单的demo中,我们将探讨Hessian的核心概念,以及如何在实际应用中使用它。 首先,我们需要理解什么是数据序列化。数据序列化是...
例如,`Hessian2Input`和`Hessian2Output`类分别用于反序列化和序列化对象。它们通过读写字节流来处理各种数据类型,包括基本类型、对象引用、集合和自定义类等。 2. **HTTP通信**:在"**com.caucho.hessian.client...