枚举型(enum)字段的序列化
Java
默认情况下枚举字段会序列为字符型,值为枚举字段的名字(即 Enum<E extends Enum<E>>
的 name()
方法的返回值)。
jackson 中可以通过设置 SerializationFeature.WRITE_ENUMS_USING_TO_STRING
或 SerializationFeature.WRITE_ENUMS_USING_INDEX
来改变默认的枚举型序列化结果。默认情况下这两个设置均为 false
,可以通过如下方式设置:
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING, true);
mapper.configure(SerializationFeature.WRITE_ENUMS_USING_INDEX, true);
return mapper.writeValueAsString(obj);
将 WRITE_ENUMS_USING_TO_STRING
设置为 true
, 将序列化为 Enum.toString()
的返回值。而 Enum.toString()
方法可以重写。
将 WRITE_ENUMS_USING_INDEX
设置为 true
则序列化为 Enum.ordinal()
的返回值(及该枚举值的索引),这时值是 Integer
型。另外 Enum.ordinal()
不可以重写。
两个同时设置为 true
时, WRITE_ENUMS_USING_INDEX
拥有较高的优先级。
/**
* Feature that determines standard serialization mechanism used for
* Enum values: if enabled, return value of <code>Enum.toString()</code>
* is used; if disabled, return value of <code>Enum.name()</code> is used.
*<p>
* Note: this feature should usually have same value
* as {@link DeserializationFeature#READ_ENUMS_USING_TO_STRING}.
*<p>
* Feature is disabled by default.
*/
WRITE_ENUMS_USING_TO_STRING(false),
/**
* Feature that determines whethere Java Enum values are serialized
* as numbers (true), or textual values (false). If textual values are
* used, other settings are also considered.
* If this feature is enabled,
* return value of <code>Enum.ordinal()</code>
* (an integer) will be used as the serialization.
*<p>
* Note that this feature has precedence over {@link #WRITE_ENUMS_USING_TO_STRING},
* which is only considered if this feature is set to false.
*<p>
* Feature is disabled by default.
*/
WRITE_ENUMS_USING_INDEX(false),
下为一个 enum
型的示例:
public enum LogLevel {
/**
* 异常
*/
Error("Error", 1),
/**
* 警告
*/
Warn("Warn", 2),
/**
* 消息
*/
Info("Info", 3),
/**
* 调试
*/
Debug("Debug", 4),
/**
* 跟踪
*/
Trace("Trace", 5);
private String name;
private int index;
LogLevel(String name, int index) {
this.name = name;
this.index = index;
}
public String getName() {
return name;
}
public LogLevel valueOf(int value) {
switch (value) {
case 1:
return LogLevel.Error;
case 2:
return LogLevel.Warn;
case 3:
return LogLevel.Info;
case 4:
return LogLevel.Debug;
case 5:
return LogLevel.Trace;
default:
return LogLevel.Info;
}
}
// // Error: java: LogLevel 中的 ordinal() 无法覆盖 java.lang.Enum 中的 ordinal()
// @Override
// public int ordinal() {
// return this.index;
// }
@Override
public String toString() {
return String.valueOf(this.index);
}
}
C#
C# 中默认序列化为对应的整形值。如果需要序列化为字符串则需要使用 JsonConverter
特性。
/// <summary>
/// 日志级别
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public LogLevel Level { get; set; } = LogLevel.Info;
保持 Java & C# 中序列化结果一致
Java 和 C# 中枚举型最大的不同就是:Java 中不能指定索引值,只能从零开始;C# 中默认也是从零开始,但是可以手动指定每个的索引值。
统一序列化成数字
虽然 Java 中 将 WRITE_ENUMS_USING_TO_STRING
设置为 true
,然后再重写 ToString
方法可以将其序列化成指定的索引值,但其类型是 String
,而不是 C# 中默认的整形。
统一序列化成名字(推荐)
在 C# 中将其序列化为字符串,这样就可以和 Java 中的默认方法一致了。