java 为什么 HttpServlet 实现了 Serializable?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/179743/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 11:18:29  来源:igfitidea点击:

Why does HttpServlet implement Serializable?

javasessionservletsserializable

提问by Andreas Petersson

In my understanding of Servlet, the Servlet will be instantiated by the Container, its init()method will be called once, and the servlet will live like a singleton until the JVM shuts down.

在我对 Servlet 的理解中,Servlet 将被 Container 实例化,它的init()方法将被调用一次,并且 servlet 将像单例一样生活,直到 JVM 关闭。

I do not expect my servlet to be serialized, since it will be constructed new when the app server recovers or is starts up normally. The servlet should hold no session-specific members, so it does not make sense for it to be written to disk and re-instantiated. Is there a practical use for this?

我不希望我的 servlet 被序列化,因为它会在应用服务器恢复或正常启动时被构造新的。servlet 不应包含特定于会话的成员,因此将其写入磁盘并重新实例化是没有意义的。这有实际用途吗?

My concerns are, that I put some non-serializable fields within there and then my app will mysteriously fail in a production environment where a different sort of session replication will take place.

我担心的是,我在其中放置了一些不可序列化的字段,然后我的应用程序将在生产环境中神秘地失败,其中将发生不同类型的会话复制。

采纳答案by skaffman

Technically, I believe the servlet container is allowed to "passivate" the servlet object to disk, in a similar way that EJB session beans can be. So you're correct to ask the question if your app will fail due to non-serializable fields.

从技术上讲,我相信 servlet 容器可以将 servlet 对象“钝化”到磁盘,这与 EJB 会话 bean 可以采用的方式类似。因此,如果您的应用程序会因不可序列化的字段而失败,那么您提出这个问题是正确的。

In practise, I've never heard of a container doing this, so it's really just legacy baggage from the bad old days of early J2EE. I wouldn't worry about it.

实际上,我从来没有听说过有容器这样做,所以它实际上只是早期 J2EE 糟糕时代的遗留包袱。我不会担心的。

回答by Rastislav Komara

HttpServlet should by serialized to disk and survive restart of servlet container. For example tomcat allows you to set up flag which enable this kind of survive. The next option is transfer using JNDI. This is not garbage, it is used only in extreme use cases.

HttpServlet 应该通过序列化到磁盘并在 servlet 容器重新启动后继续存在。例如 tomcat 允许您设置标志以启用这种生存。下一个选项是使用 JNDI 进行传输。这不是垃圾,它仅用于极端用例。

回答by matt b

Google seems to suggest that this was done so that container authors can have the option, if they want it.

谷歌似乎建议这样做是为了容器作者可以选择,如果他们想要的话。

You're correct that the servlet should hold no session-specific members, in fact I would think you'd want as little state at all as possible. If you store everything in either Session or ServletConfig, I think you'd be able to survive serialization.

您认为 servlet 不应该包含特定于会话的成员是正确的,实际上我认为您希望尽可能少的状态。如果您将所有内容都存储在 Session 或 ServletConfig 中,我认为您将能够在序列化中幸存下来。

回答by anjanb

Just like Session objects are serialized to survive caches for those servletcontainers giving the cluster option, there might be an option for a container to transfer a Servlet instance as well to another cluster node ?? I'm just guessing here

就像 Session 对象被序列化以在那些提供集群选项的 servletcontainers 的缓存中存活一样,容器可能也有一个选项可以将 Servlet 实例传输到另一个集群节点?我只是在这里猜测

回答by Maciek Kreft

Serializable is used as a marker interfacefor session's attributes in distributed environment.

Serializable 用作分布式环境中会话属性的标记接口

SRV.7.7.2 Distributed Environments (JSR-154)

Within an application marked as distributable, all requests that are part of a session must be handled by one Java Virtual Machine (“JVM”) at a time. The container must be able to handle all objects placed into instances of the HttpSession class using the setAttribute or putValue methods appropriately. The following restrictions are imposed to meet these conditions:

  • The container must accept objects that implement the Serializable interface.
  • Migration of sessions will be handled by container-specific facilities.

The distributed servlet container must throw an IllegalArgumentException for objects where the container cannot support the mechanism necessary for migration of the session storing them.

The distributed servlet container must support the mechanism necessary for migrating objects that implement Serializable.

(...)

The Container Provider can ensure scalability and quality of service features like load-balancing and failover by having the ability to move a session object, and its contents, from any active node of the distributed system to a different node of the system.If distributed containers persist or migrate sessionsto provide quality of service features, they are not restricted to using the native JVM Serialization mechanism for serializing HttpSessions and their attributes. Developers are not guaranteed that containers will call readObject and writeObject methods on session attributes if they implement them, but are guaranteed that the Serializable closure of their attributes will be preserved.

SRV.7.7.2 分布式环境 (JSR-154)

在标记为可分发的应用程序中,作为会话一部分的所有请求必须一次由一个 Java 虚拟机(“JVM”)处理。容器必须能够适当地使用 setAttribute 或 putValue 方法处理放置到 HttpSession 类实例中的所有对象。为满足这些条件,施加了以下限制:

  • 容器必须接受实现 Serializable 接口的对象
  • 会话的迁移将由特定于容器的设施处理。

对于容器不能支持迁移存储它们的会话所需的机制的对象,分布式 servlet 容器必须抛出 IllegalArgumentException 。

分布式 servlet 容器必须支持迁移实现 Serializable 的对象所需的机制 。

(...)

Container Provider 能够将会话对象及其内容从分布式系统的任何活动节点移动到系统的不同节点,从而确保可扩展性和服务质量,例如负载平衡和故障转移如果分布式容器通过持久化或迁移会话来提供服务质量特性,则它们不限于使用本机 JVM 序列化机制来序列化 HttpSessions 及其属性。开发人员不能保证容器会在会话属性上调用 readObject 和 writeObject 方法(如果他们实现它们),但可以保证其属性的 Serializable 闭包将被保留