我试图通过实现一个简单的REST API来学习Spring Boot。
我的理解是,如果我需要通过线路传输对象,那么该对象应该实现Serializable。
在网络上的许多示例中,包括官方示例,需要从服务器传输到客户端的域类(反之亦然)不实现Serializable。
例如:https://spring.io/guides/gs/rest-service/
但在某些情况下,他们会:
是否有关于何时实施Serializable的一般经验法则?
答案 0 :(得分:15)
要更新此信息,有关Serializable的建议已更改,建议目前似乎为Don’t use Serializable for anything。
使用Java序列化API意味着您需要在线路的另一端使用Java来反序列化对象,因此您必须控制反序列化的代码以及序列化的代码。
这通常与REST应用程序无关,使用应用程序响应是其他人的代码的业务,通常在组织外部。在构建REST应用程序时,尝试避免对正在使用它的内容施加限制是正常的,选择一种技术无关且可广泛使用的格式。
使对象可序列化的一些原因是:
所以你可以把它放在HttpSession
因此您可以在分布式应用程序中的层之间传递它
因此您可以将其保存到文件系统并稍后恢复(例如,您可以使队列的内容可序列化并在应用程序关闭时保存队列内容,从保存位置读取时应用程序开始将队列恢复到关闭时的状态)。
在所有这些情况下,您进行序列化,以便将某些内容保存到文件系统或通过网络发送。
答案 1 :(得分:3)
序列化对象有很多种方法。 Java的对象序列化只是其中之一。来自official documentation:
序列化对象意味着将其状态转换为字节流
REST API通常发送和接收JSON或XML。在这种情况下,序列化对象意味着将其状态转换为String
。
"通过电线发送物体"之间没有直接联系。并实施Serializable
。您使用的技术决定了是否必须实施Serializable
。
答案 2 :(得分:3)
您提到的具体示例不会通过网络传输对象。从示例链接中我看到控制器方法返回带有ResponseBody
注释的域对象。仅仅因为方法的返回类型是域对象,所以不必将整个对象发送到客户端。 Spring mvc框架中的一个处理程序方法在内部拦截调用,并确定方法返回类型不会转换为直接ModelAndView
对象。 RequestResponseBoodyMethodProcessor
,它处理这些带注释的方法的返回值,并使用其中一个消息转换器将返回对象写入http响应主体。在使用的消息转换器为MappingJackson2HttpMessageConverter
的情况下。因此,如果要遵循相同的编码样式,则不需要为域对象实现Serializable
。
对于默认情况下从spring提供的Http消息转换器,请查看此link。该列表是安静的,但并非详尽无遗,如果需求出现,您可以为用户实现自己的自定义消息转换器。
答案 3 :(得分:3)
这是一个很好的问题,何时实现Serializable接口。
这些链接可以提供一些有用的内容:
Serializing java.io.Serializable instance into JSON with Spring and Jackson JSON
When and why JPA entities should implement Serializable interface?
我有时会想到这一点,我想
因为Java是一种开源语言,并且有更多的库由第三方提供。为了告诉谁将序列化和反序列化对象,java官方声明了一个constract接口,使得传输变得容易和安全通过不同的库。
这只是一个概念,大多数第三方库在检查实现此结构时可以序列化/反序列化。杰克逊的jar库不使用它。
所以你可以认为,如果你在自己的系统中使用序列化/反序列化对象数据,并且简单的过程,就像序列化和响应它(在Spring MVC中的jackson),你不需要实现它。 但是如果你在其他jar库中使用过,喜欢在HttpSession或其他第三方组件/库中保存,你应该(或者必须)实现Serializable,否则库会抛出一个异常来告诉你它所知道的constract接口不提供。
但是他们说在序列化自定义类时实现Serializable是一个好习惯和最佳属性。 :)
答案 4 :(得分:0)
如果您正在使用缓存进行数据库操作,则应该序列化,通常第三方缓存提供程序(例如hazle cast,Jboss缓存等)在内部对对象进行序列化/反序列化,在这种情况下,模型类应实现Serializable来促进缓存