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

发布于 2024-10-29 21:41:02 字数 866 浏览 3 评论 0原文

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

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

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

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

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

所以我有很多问题:

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

I am defining a simple "key-value store" service in GWT; I will be writing the server but letting others write clients so it should be as simple as possible. I want the client to be able to use String keys, but values of any serializable type. So I defined the interface:

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

This works perfectly, but there's one problem: Eclipse gives the following warning on both methods:

Checking all subtypes of Object which qualify for serialization

Googling that warning, it seems like GWT is going to generate a piece of code for every single type in the program. Therefore, this could be quite expensive. I'm confused because I thought that all types in the Serializable interface already had serialisation code, and it could just call that (but perhaps that serialisation code is only generated in this case).

So I have a number of questions:

  • Is this going to make the client code much a) bigger and/or b) slower? How serious is that problem?
  • I see GWT provides a separate interface IsSerializable. Can I use that instead? I tried it but I noticed that basic classes like String and Integer do not implement this interface.
  • If I make the RPC layer use byte[] instead, but provide a wrapper method for my clients to serialize a java.io.Serializable into a byte[], will that get around the problem, or will it end up with the same code bloat problem I started with?
  • Is there a better way to implement a key-value store which allows arbitrary-type values without too much work on behalf of the client?
  • If I stick with Serializable, is there a way to suppress that warning?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不醒的梦 2024-11-05 21:41:02

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

是的。 IsSerialized 优于 java.io.Serializable。 GWT 常见问题解答列出了出现这种情况的原因所以:

  • GWT 序列化的语义远没有标准 Java 序列化那么复杂,因此使用 java.io.Serialized 作为标记接口意味着 GWT 序列化系统的能力比其实际能力要多。
  • 相反,GWT 的序列化机制比标准 Java 的序列化机制更简单,因此使用 java.io.Serialized 意味着用户需要担心的事情(例如序列化版本 ID)比实际情况要多。
  • GWT 仅实现完整 Java JRE 类的一个子集,并且在 java.io 中没有具体实现任何内容。使用 java.io.Serialized 作为 GWT RPC 序列化标记接口会淡化 java.io 在 GWT 应用程序中不可用的消息。


>

如果我让 RPC 层使用 byte[] 代替,但为我的客户端提供一个包装方法来将 java.io.Serialized 序列化为 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 序列化(从服务器到数据存储)进行序列化。

编辑回复评论:

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

是的,客户必须为每种类型创建一个新商店。如果它真的困扰你,解决这个问题的一个解决方案是创建一个新的接口 MySerialized,它扩展了 IsSerializes 和 java.io.Serializes;但是每个对象都必须实现它,这会创建对您的项目的依赖关系。

另外,它不要求对象既可序列化又可序列化吗?

是的,这是一个好处。否则,您可能会面临服务器端对象不是 java.io.Serialized 的风险;如果您尝试将其提供给方法 ObjectOutputStream#writeObject,异常就会当着你的面爆炸。

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

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

I see GWT provides a separate interface IsSerializable. Can I use that instead? I tried it but I noticed that basic classes like String and Integer do not implement this interface.

Yes. IsSerializable is preferred over java.io.Serializable. The GWT FAQ lists the reasons why this is so:

  • The semantics of GWT's serialization are much less sophisticated than standard Java serialization, and so to use java.io.Serializable as the marker interface would imply that GWT's serialization system is capable of more than it actually is.
  • Conversely, GWT's serialization mechanism is simpler than standard Java's, and so to use java.io.Serializable would imply that users have more to worry about (such as serialization version IDs) than they actually do.
  • GWT implements only a subset of the full Java JRE classes, and specifically implements nothing in java.io. To use java.io.Serializable as the GWT RPC serialization marker interface dilutes the message that java.io is not usable within a GWT application.

>

If I make the RPC layer use byte[] instead, but provide a wrapper method for my clients to serialize a java.io.Serializable into a byte[], will that get around the problem, or will it end up with the same code bloat problem I started with?

Bad idea. In this case, the serialization from objects to byte[] will happen in JavaScript on the client side. Yes, serialization is possible on the client side, but with the GWT protocol; that's not Java serialization. The browser will not do that well.

Is there a better way to implement a key-value store which allows arbitrary-type values without too much work on behalf of the client?

Unfortunately, I think you will not be able to get away with one true method for all classes. I suggest you try the following interface:

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);
}

The generics ensure that the object has both interfaces, so that you can serialize then both with the GWT protocol (from client to server) and Java serialization (from server to data store).

Edit Answering comments:

With that last solution, doesn't the generic mean the store can only store a single type of object, and if the client wants to store a different one, he has to create a new store?

Yes, the client would have to create a new store for each type. If it really bothers you, A solution around this is to create a new interface MySerializable, which extends IsSerializable and java.io.Serializable; but then each object will have to implement that, which creates a dependency on your project.

Also doesn't it require that the object is both Serializable and IsSerializable?

Yes, and that's a benefit. Otherwise, you risk having an object on the server side that is not java.io.Serializable; if you try to supply it to method ObjectOutputStream#writeObject, an exception will blow up at your face.

Lastly, what about my first question: is just using io.Serializable actually going to affect the code size / performance?

I cannot say that from real usage, but I don't think so: both are simply marker interfaces. The GWT serialization will be the same for either.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文