Java 中的任何服务器、框架或 J2EE 本身是否仍在使用序列化?

Han*_*yer 3 java serialization wildfly sonarlint jakarta-ee

\xe2\x80\x9cSerialized\xe2\x80\x9d 类中有一个名为Fields 的声纳规则,该规则应该是瞬态的或可序列化的。当您向类中添加不可序列化的字段时,它就会出现。该规则规定:

\n
\n

例如,在负载下,大多数 J2EE 应用程序框架都会将对象刷新到磁盘,而具有非瞬态、不可序列化数据成员的所谓可序列化对象可能会导致程序崩溃,并为攻击者打开大门。

\n
\n

这对我来说听起来已经过时了。在《Effective Java 第 3 版》中指出,在开发新软件时,序列化并不相关。此外,从 Java 中删除序列化是 Oracle 的“长期目标”。Java 首席架构师 Mark Reinhold 本人表示

\n
\n

\xe2\x80\x9e1997 年的序列化是一个可怕的错误。\xe2\x80\x9c

\n
\n

Spring 框架是否可以刷新对象的问题已经在这里被问过:

\n\n

所以我问一个问题:\n现代应用程序服务器、框架或 J2EE 实现本身(特别是与 CDI、EJB、JPA 交互的 Java 组件)是否会在重负载下将对象刷新到磁盘?

\n

或者这个说法已经过时了?

\n

Gee*_*nte 9

长话短说

如果您没有实现可分发的 Web 应用程序,没有启用会话持久性,并且只使用内存中的缓存,那么您可能不需要在任何地方使用 Serialized。

解释

对于会话复制,Java 序列化仍然是最新 Servlet 规范的必须条件:https://jakarta.ee/specifications/servlet/5.0/jakarta-servlet-spec-5.0.html#distributed-environments

一个常见的用例是,如果负载均衡器后面有多台服务器,并且您登录一台服务器,您将获得一个 JSESSIONID cookie。如果负载均衡器将您发送到不同的服务器来处理下一个请求,您的登录属性和其他会话范围的属性将被序列化并复制到新服务器上,因此您的 JSESSIONID 在那里仍然有效。

需要对会话范围的属性进行序列化的另一个用例是应用程序服务器决定将会话交换到磁盘时。例如,对于 Tomcat 8,可以将其配置为在内存中保存的会话过多或服务器重新启动时激活,并且您希望保持会话处于活动状态。请参阅 https://tomcat.apache.org/tomcat-9.0-doc/config/manager.html

对于此类用例,默认情况下每个 Servlet-5.0 兼容的应用程序服务器都必须支持 Http 会话中的可序列化对象。

对于某些服务器,可以使用 Jackson-JSON 序列化或类似的东西来调整或覆盖它。请参阅例如如何在 spring 中使用 jackson 代替 JdkSerializationRedisSerializer

另一个常见用例是缓存。这用于保持对象尽可能快地可访问,最好是在内存中,但可能暂时卸载到磁盘或外部缓存服务器。它有一个标准 API (JSR-107),明确选择不需要可序列化对象,但大多数实现仍然默认使用 java 序列化作为卸载部分。

您可以再次调整它们以支持其他序列化机制,例如 ehcache: https: //www.ehcache.org/documentation/3.8/serializers-copiers.html