Hessian 的字段序列化

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的协议。

作者: inter12

在这苦短的人生中,追求点自己的简单快乐

发表评论

电子邮件地址不会被公开。 必填项已用*标注