GWT-RPC服务是否应该使用java.io.Serializable作为参数类型?

时间:2011-04-04 12:39:42

标签: gwt serialization gwt-rpc

我在GWT中定义了一个简单的“键值存储”服务;我将编写服务器,但让其他人编写客户端,因此它应该尽可能简单。我希望客户端能够使用String键,但任何可序列化类型的值。所以我定义了界面:

public void put(String key, java.io.Serializable value);
public java.io.Serializable get(String key);

这很有效,但有一个问题:Eclipse对这两种方法都给出了以下警告:

  

检查符合序列化条件的Object的所有子类型

谷歌搜索该警告,似乎GWT将为程序中的每一种类型生成一段代码。因此,这可能非常昂贵。我很困惑,因为我认为Serializable接口中的所有类型都已经有序列化代码,它可以调用它(但可能只是在这种情况下生成序列化代码)。

所以我有很多问题:

  • 这是否会使客户端代码变得更大和/或b)更慢?这个问题有多严重?
  • 我看到GWT提供了一个单独的接口IsSerializable。我可以用它吗?我尝试了但是我注意到像String和Integer这样的基本类没有实现这个接口。
  • 如果我改为使用byte[],但为我的客户提供了一个包装器方法,以便将java.io.Serializable序列化为byte[],这样可以解决问题,还是会最终我遇到了与我开始时相同的代码膨胀问题?
  • 是否有更好的方法来实现一个键值存储,允许任意类型的值代表客户端而不需要太多工作?
  • 如果我坚持使用Serializable,有没有办法抑制该警告?

1 个答案:

答案 0 :(得分:2)

  

我看到GWT提供了一个单独的接口IsSerializable。我可以用它吗?我试了但是我注意到像String和Integer这样的基本类没有实现这个接口。

是。 IsSerializable优于java.io.Serializable。 GWT FAQ列出了原因:

  
      
  • GWT序列化的语义远比标准Java序列化复杂,因此使用java.io.Serializable作为标记接口意味着GWT的序列化系统能够实现比实际更多的能力。
  •   
  • 相反,GWT的序列化机制比标准Java更简单,因此使用java.io.Serializable意味着用户比实际更需要担心(例如序列化版本ID)。
  •   
  • GWT仅实现完整Java JRE类的一部分,并且在java.io中没有特别实现。使用java.io.Serializable作为GWT RPC序列化标记接口会稀释java.io在GWT应用程序中不可用的消息。
  •   

>

  

如果我使RPC层使用byte [],但是为我的客户端提供了一个包装器方法来将java.io.Serializable序列化为byte [],那么它会解决问题,还是会以我开始使用相同的代码膨胀问题?

糟糕的主意。在这种情况下,从对象到byte []的序列化将在客户端的JavaScript中进行。是的,可以在客户端进行序列化,但使用GWT协议;这不是Java序列化。浏览器不会那么好。

  

有没有更好的方法来实现一个键值存储,它允许任意类型的值而不代表客户端进行太多工作?

不幸的是,我认为你无法逃脱所有课程的真正方法。我建议你尝试以下界面:

interface Store<T extends Serializable & IsSerializable> {
void put(String key, String value);
void put(String key, Number value);
void put(String key, T value);

Integer getInt(String key);
Double getDouble(String key);
BigDecimal getBigDecimal(String key);
String getString(String key);
IsSerializable get(String key);
}

泛型确保对象具有两个接口,因此您可以使用GWT协议(从客户端到服务器)和Java序列化(从服务器到数据存储)进行序列化。

修改回复评论:

  

使用最后一个解决方案,通用意味着商店只能存储单一类型的对象,如果客户想要存储不同的对象,他必须创建一个新商店吗?

是的,客户端必须为每种类型创建一个新商店。如果它真的困扰你,解决这个问题的方法是创建一个新的接口MySerializable,它扩展了IsSerializable和java.io.Serializable;但是每个对象都必须实现它,这会对你的项目产生依赖。

  

也不要求对象是Serializable和IsSerializable吗?

是的,这是一个好处。否则,您可能会在服务器端拥有一个不是java.io.Serializable的对象;如果你试图将它提供给方法ObjectOutputStream#writeObject,那么你的脸上就会出现例外情况。

  

最后,我的第一个问题是:只是使用io.Serializable实际上会影响代码大小/性能吗?

我不能说从实际用途,但我不这么认为:两者都只是标记接口。两者的GWT序列化都是相同的。