Java 序列化介绍及 Redis 序列化方式

目录

 


Java 序列化介绍及 Redis 序列化方式

什么是 java 序列化?什么情况下需要序列化?

回到顶部

1、序列化与反序列化

  • 序列化:将 Java 对象转换成字节流的过程。
  • 反序列化:将字节流转换成 Java 对象的过程。
回到顶部

2、什么情况下需要序列化

  • 想把内存中的对象状态保存到一个文件中或者数据库中的时候(最常用,如保存到 redis);
  • 想用套接字在网络上传送对象的时候;
  • 想通过 RMI 传输对象的时候;
回到顶部

3、序列化的实现

类实现 Serializable 接口即可,这个接口没有需要实现的方法。实现 Serializable 接口是为了告诉 jvm 这个类的对象可以被序列化。

回到顶部

4、注意事项

  • 某个类可以被序列化,则其子类也可以被序列化
  • 声明为 static 和 transient 的成员变量,不能被序列化。static 成员变量是描述类级别的属性,transient 表示临时数据
  • 反序列化读取序列化对象的顺序要保持一致
回到顶部

5、具体使用

以 User 实体类为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Data
@EqualsAndHashCode(callSuper = false)
@AllArgsConstructor
@NoArgsConstructor
// 实现序列化
public class User implements Serializable {

<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-type">long</span> serialVersionUID=<span class="hljs-number">1L</span>;

<span class="hljs-meta">@ApiModelProperty(value = "主键ID")</span>
<span class="hljs-meta">@TableId(value = "id", type = IdType.AUTO)</span>
<span class="hljs-keyword">private</span> Long id;

<span class="hljs-meta">@ApiModelProperty(value = "姓名")</span>
<span class="hljs-keyword">private</span> String name;

<span class="hljs-meta">@ApiModelProperty(value = "年龄")</span>
<span class="hljs-keyword">private</span> Integer age;

}

测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Test
public void test1() throws IOException, ClassNotFoundException {
// 序列化对象 User
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.txt"));
User user = new User(2L, "haha", 13);
oos.writeObject(user);
// 清除缓存、关闭
oos.flush();
oos.close();

<span class="hljs-comment">//反序列化</span>
<span class="hljs-type">ObjectInputStream</span> <span class="hljs-variable">ois</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ObjectInputStream</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">FileInputStream</span>(<span class="hljs-string">"user.txt"</span>));
<span class="hljs-type">User</span> <span class="hljs-variable">readUser</span> <span class="hljs-operator">=</span> (User) ois.readObject();
System.out.println(readUser.toString());

}

在项目根目录可以找到 user.txt 文件并看到输出结果。

参考资料 1:https://blog.csdn.net/meism5/article/details/90413987

参考资料 2:https://blog.csdn.net/Mr_EvanChen/article/details/79724426

回到顶部

6、Redis 序列化方式

我使用的是 spring-data-redis, spring-data-redis 默认采用的序列化策略有两种,一种是 String 的序列化策略,一种是 JDK 的序列化策略

redisTemplate 可自定义各种 key 和各种 value 的序列化方式:

  • defaultSerializer: 默认序列化策略
  • key:普通 key, 非 hash
  • value:普通 value, 非 hash
  • hashKey:hash 的 filed
  • hashValue:hash 的 value

总共有以下几个序列化类:

  • Jackson2JsonRedisSerializer: 跟 JacksonJsonRedisSerializer 实际上是一样的
  • JacksonJsonRedisSerializer: 序列化 object 对象为 json 字符串
  • JdkSerializationRedisSerializer: 序列化 java 对象(被序列化的对象必须实现 Serializable 接口), 无法转义成对象。
  • StringRedisSerializer: 简单的字符串序列化
  • GenericToStringSerializer: 类似 StringRedisSerializer 的字符串序列化
  • GenericJackson2JsonRedisSerializer: 类似 Jackson2JsonRedisSerializer,但使用时构造函数不用特定的类参考以上序列化, 自定义序列化类。

推荐使用 GenericJackson2JsonRedisSerializer 或 Jackson2JsonRedisSerializer 。

**StringRedisTemplate ** 默认采用的是 String 的序列化策略,保存的 key 和 value 都是采用此策略序列化保存的。序列化类为:StringRedisSerializer
**RedisTemplate ** 默认采用的是 JDK 的序列化策略,保存的 key 和 value 都是采用此策略序列化保存的。序列化类为:JdkSerializationRedisSerializer

回到顶部

7、Redis 推荐序列化类

key 和 hashKey: 推荐使用 StringRedisSerializer: 简单的字符串序列化

value 和 hashValue: 推荐使用GenericJackson2JsonRedisSerializer: 类似 Jackson2JsonRedisSerializer,但使用时构造函数不用特定的类

参考资料:https://blog.csdn.net/y532798113/article/details/82690781