【问题标题】:What is the best way to transmit Java objects over a network [closed]通过网络传输 Java 对象的最佳方式是什么[关闭]
【发布时间】:2009-12-02 16:22:07
【问题描述】:

我正在尝试将特定类的对象从一台服务器传输到另一台服务器。

我正在查看的选项是:

  • 将数据序列化为 JSON 并发送 它使用 HTTP 通过网络传输,并且 在另一端反序列化。
  • 将数据序列化为某种二进制形式并使用 TCP 传输 插座。

这方面的最佳做法是什么?有什么陷阱?

理想情况下,我希望对接口进行版本控制,以便发送方和接收方可以独立升级。

我正在考虑 JSON 方法,因为我已经有将对象序列化/反序列化为 JSON 的代码。

【问题讨论】:

  • 您需要通过 Intranet 还是 Internet 支持此功能?

标签: java json remoting


【解决方案1】:

每当我需要传输 Java 对象时,假设 JVM 版本相似,我总是使用纯 Java 序列化 (Sun official tutorial):它更简单,您不必关心项目或聚合的传输链,因为序列化已经关心它(如果你正确地实现它)。

因此,如果您想传输由许多子对象组成的复杂对象,您不必拆分它,发送它并重新组合它:您只需发送对象,它已经包含了已经包含的所有内容。

编辑

关于 RMI:我将它与序列化一起使用,它就像一个魅力!我曾经开发过远程摇摆(通过 TCP 发送 JPanel)..

  1. RMI 可以帮助您调用远程方法并从主服务器获取对象
  2. 客户端可以使用序列化(通过不同的套接字)发回对象或将它们作为参数传递给 RMI 调用,这应该是个人喜好

当然我不知道你到底想做什么,但是这两个工具都很好用,也可以正交使用。

【讨论】:

  • 我有很好的经验,只要在两端运行相同版本的代码,在相同版本的 JVM 上等等!
  • 这就是我写“假设类似 JVM 版本”的原因。根据我的个人经验,它也适用于不同的版本,但它们的差异很小(比如不同的更新)。
【解决方案2】:

如果两端都是Java写的,就用Java自己的序列化吧。

另一方面,使用 JSON、XML 或 YAML 将更容易调试,因为传输的内容将是可读的。

【讨论】:

    【解决方案3】:

    我知道这个帖子现在已经过时了,但我只是偶然发现了它,并认为我会为未来的读者提供 2 美分...

    除非出于某种原因需要 JSON,否则实际上不需要 2 个应用程序使用它进行通信。我同意上面的 Avro 建议。 Avro 允许您编写业务逻辑代码并为您处理序列化/反序列化。它将生成一个服务器端接口来实现(基于您提供的模式)和一个客户端代理存根来调用服务。如果需要,它也可以序列化为其他格式。

    没有太多指导文档或示例,但这里有一些看起来不错的:

    这里是使用套接字服务器的教程: http://gbif.blogspot.com/2011/06/getting-started-with-avro-rpc.html

    这是一个通过 http 使用 Avro 的开源项目/演示: http://code.google.com/p/avro-http-example/

    【讨论】:

      【解决方案4】:

      我建议使用带有 JSON 编码的 Avro;您将在仍然使用 HTTP 和 JSON 的同时获得所需的版本控制支持,并且您不必自己编写序列化/反序列化代码。请参阅 http://hadoop.apache.org/avro/docs/current/spec.html 了解 Avro 功能的简明描述,如果您在开始使用时遇到任何问题,请在邮件列表中留言或加入 #avro 频道。

      【讨论】:

        【解决方案5】:

        一些选项:

        • 如果您需要通过公共网络执行此操作,请使用 json http 方法,因为您不会遇到防火墙问题 - 您可以通过端口 80
        • 如果您在 Intranet 上执行此操作的最快方法(从设置和可维护性的角度来看)可能是老式的 Java rmi,它只需要您定义远程接口并连接到 rmi 服务器,您可以在几分钟内启动并运行,并对远程对象/服务进行持续更改,而不用大惊小怪。在幕后,这只是使用 java 序列化
        • 如果您的需求对性能敏感(低延迟、高吞吐量),您可以使用类似google protocol buffers
        • 还可以查看Externalizable 自定义序列化接口

        【讨论】:

          【解决方案6】:

          为什么是 JSON?这通常用于 Web 应用程序。

          创建一个可以返回所需 Java 对象的 Web 服务会更有意义。那么你就不用担心序列化/反序列化了。

          【讨论】:

            【解决方案7】:

            您的选择分为仅数据解决方案和数据加行为解决方案。

            对于数据,可以使用JSON,也可以使用Java的序列化。 JSON 很简单,但您必须使用自己的类包装器。使用 Java 的序列化可以很好地工作,因为编组问题是众所周知的并且以一致的方式处理。一种变体是在本地和远程系统上提供 Java 类,但如果您这样做,您最好继续执行 RMIRMI 很好,因为您不必为远程端编写单独的类,但是在分发对象时确实要注意一些问题,例如确保设置类的 Serial ID或者必须将确切的二进制类文件分发到远程系统。您可以使用 RPC 来做到这一点,但如果您走得那么远,您不妨创建一个 Web 服务并使用 SOAP

            【讨论】:

              【解决方案8】:

              多年来,我尝试了很多选项或序列化/反序列化,包括 JSON、XML、SOAP、protobuf 和其他一些我不好意思在这里命名的选项 :-)

              现在,我们几乎只将 JSON 编码用于 Java 到 Java 和 JS 到 Java 的传输,甚至用于存储内部数据(除非二进制数据量使 JSON 格式效率太低)。 JSON 的优点是简单、重量轻,无论是在负载方面,还是在我们接触过的所有语言的序列化解决方案的实现复杂性和可用性方面。它还有助于拥有“标准”持久性框架。

              最近Jackson 对我们来说效果很好。 Jabsorb 也有很好的(反)序列化包。

              版本控制: JSON 没有内置的版本控制支持(Avro 可能有一些东西),所以你必须自己运行。保留主要/次要版本编号方案通常是个好主意:主要版本号不兼容,次要版本号向后兼容,因此客户端 1.2 可以与服务器 1.5 通信,但不能与服务器 2.1 通信。

              陷阱:

              • 转换 Java 泛型(如 TreeMap)有时具有挑战性。
              • 默认情况下,某些实现可能会嵌入实现类名称,这会降低协议的抗更改性。您可能不想在线路上做任何多余的事情。

              【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-03-12
              • 1970-01-01
              • 1970-01-01
              • 2012-03-31
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多