java 除了提供transient关键字之外,我们可以拒绝序列化java对象吗

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1292474/
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 15:59:19  来源:igfitidea点击:

Can we deny a java object from serialization other than giving transient keyword

javaserializationjava-custom-serialization

提问by Biju CD

We can avoid serialising fields by using the transientkeyword. Is there any other way of doing that?

我们可以通过使用transient关键字来避免序列化字段。有没有其他方法可以做到这一点?

回答by adatapost

http://java.sun.com/javase/6/docs/platform/serialization/spec/security.html

http://java.sun.com/javase/6/docs/platform/serialization/spec/security.html

SUMMARY:Preventing Serialization of Sensitive Data Fields containing sensitive data should not be serialized; doing so exposes their values to any party with access to the serialization stream. There are several methods for preventing a field from being serialized:

  1. Declare the field as private transient.
  2. Define the serialPersistentFields field of the class in question, and omit the field from the list of field descriptors.
  3. Write a class-specific serialization method (i.e., writeObject or writeExternal) which does not write the field to the serialization stream (i.e., by not calling ObjectOutputStream.defaultWriteObject).

总结:Preventing Sensitive Data 包含敏感数据的字段不应该被序列化;这样做会将它们的值暴露给可以访问序列化流的任何一方。有几种方法可以防止字段被序列化:

  1. 将该字段声明为私有瞬态。
  2. 定义相关类的 serialPersistentFields 字段,并从字段描述符列表中省略该字段。
  3. 编写一个特定于类的序列化方法(即 writeObject 或 writeExternal),该方法不会将字段写入序列化流(即,通过不调用 ObjectOutputStream.defaultWriteObject)。

Here are some links.

这里有一些链接。

Declaring serialPersistenetFields.

声明 serialPersistenetFields。

Serialization architecture specification.

序列化架构规范。

Security in Object Serialization.

对象序列化中的安全性。

回答by T.J. Crowder

If for some reason transient doesn't suit, you can do the serialization directly by overriding the writeObject and readObjectmethods. Then you can include or omit any fields you need.

如果由于某种原因瞬态不适合,您可以通过覆盖writeObject 和 readObject方法直接进行序列化。然后您可以包含或省略您需要的任何字段。

回答by Paul Keeble

This is what transient means as a a keyword. Its whole purpose is to stop the serialization of the data for whatever reason.

这就是瞬态作为关键字的含义。它的全部目的是出于任何原因停止数据的序列化。

If you wanted a finer grain control over the process you can use the writeObject/readObject methods that the ObjectOutputStream/ObjectInputStream use as part of the serialization process, and you could combine that with some custom annotations or any logic you wanted.

如果您想要对过程进行更精细的控制,您可以使用 ObjectOutputStream/ObjectInputStream 用作序列化过程的一部分的 writeObject/readObject 方法,并且您可以将其与一些自定义注释或任何您想要的逻辑相结合。

private void readObject(java.io.ObjectInputStream stream)
 throws IOException, ClassNotFoundException;
private void writeObject(java.io.ObjectOutputStream stream)
 throws IOException

回答by dfa

You can create your own protocol with the Externalizableinterface, that in my opinion is a nicer than Serializable since it doesn't contains private methods hooked by the JVM (writeObjectand readObject). Instead of implementing the Serializableinterface, you can implement Externalizable, which contains two methods:

您可以使用Externalizable接口创建自己的协议,在我看来,它比 Serializable 更好,因为它不包含由 JVM (writeObjectreadObject)挂钩的私有方法。Serializable您可以实现Externalizable,而不是实现接口,它包含两个方法:

public void writeExternal(ObjectOutput out) throws IOException;
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException

Unlike using Serializablenothing is provided for free now, though. That is, the protocol is entirely in your hands, overring transient/non triansient fields, etc.

不过,与使用Serializable什么都不一样,现在免费提供。也就是说,协议完全掌握在你手中,覆盖瞬态/非三角场等。