使用 Jackson 自定义枚举常量名称
Customizing enum constant names with Jackson
我有一个枚举定义为
public enum Locale {
EN_US, ES_MX
}
然而,这些语言环境在数据中被写为带连字符的小写字符串,如 en-us
和 es-mx
。
有没有办法将这些小写字符串映射到相应的枚举常量?喜欢 en-us
到 EN_US
?
编辑
让我提供更多信息。我有一个对象 class.
public class Song {
private Map<Locale, String> songName;
private int durationMillis;
}
歌曲的名称可能因语言环境而异。所以我在各种语言环境中为歌曲名称创建了一个映射。
我有一个包含歌曲信息的 JSON 文件。内容如下:
{
"songs": [
{
"songName": {"en-us":"Song name in US english", "es-mx": "Song name in Spanish"},
"durationMillis": 100000
},
{
"songName": {"en-us": "another song name - English"},
"durationMillis": 200000
}
]
}
我再定义一个class.
public class Songs {
private Set<Song> songs;
}
我使用 FasterXml 的 ObjectMapper
加载 JSON 作为 Songs
class.
的对象
Songs songs = objectMapper.readValue(jsonStr, Songs.class);
上面这行现在崩溃了,因为 ObjectMapper
无法将 en-us
字符串映射到 Locale.EN_US
。
我总是可以编辑枚举并将其定义为
public enum Locale {
EN_US("en-us"),
ES_MX("es-mx");
private String value;
Locale(String val){
value = val;
}
}
但我在某处看到了一种更聪明的方法,它将小写连字符字符串转换为大写下划线文字。你能告诉我那个解决方案吗?
我需要一个解决方案,以便 FasterXml 的 ObjectMapper
可以将字符串映射到枚举。
因为 Jackson 2.6, you can annotate your enum constants with @JsonProperty
to give them a custom name. The javadoc 状态
Starting with Jackson 2.6 this annotation may also be used to change
serialization of Enum
like so:
public enum MyEnum {
@JsonProperty("theFirstValue") THE_FIRST_VALUE,
@JsonProperty("another_value") ANOTHER_VALUE;
}
在你的情况下,你会使用
public enum Locale {
@JsonProperty("en-us") EN_US, @JsonProperty("es-mx") ES_MX
}
或者,假设所有枚举常量都遵循相同的命名模式,您可以使用 @JsonValue
。在您的枚举类型中定义一个用 @JsonValue
注释的实例方法,并使用您的命名策略实现它。例如,
@JsonValue
public String forJackson() {
return name().toLowerCase().replace('_', '-');
}
您将受益于
when use for Java enums, one additional feature is that value returned
by annotated method is also considered to be the value to deserialize
from, not just JSON String to serialize as. This is possible since set
of Enum values is constant and it is possible to define mapping, but
can not be done in general for POJO types; as such, this is not used
for POJO deserialization.
它将用于序列化和反序列化。
避免使用已经出现在 JDK 中的名称来命名您的类型。 Java 已经提供了常用的 Locale
类型。考虑重命名您的 class。
我有一个枚举定义为
public enum Locale {
EN_US, ES_MX
}
然而,这些语言环境在数据中被写为带连字符的小写字符串,如 en-us
和 es-mx
。
有没有办法将这些小写字符串映射到相应的枚举常量?喜欢 en-us
到 EN_US
?
编辑 让我提供更多信息。我有一个对象 class.
public class Song {
private Map<Locale, String> songName;
private int durationMillis;
}
歌曲的名称可能因语言环境而异。所以我在各种语言环境中为歌曲名称创建了一个映射。
我有一个包含歌曲信息的 JSON 文件。内容如下:
{
"songs": [
{
"songName": {"en-us":"Song name in US english", "es-mx": "Song name in Spanish"},
"durationMillis": 100000
},
{
"songName": {"en-us": "another song name - English"},
"durationMillis": 200000
}
]
}
我再定义一个class.
public class Songs {
private Set<Song> songs;
}
我使用 FasterXml 的 ObjectMapper
加载 JSON 作为 Songs
class.
Songs songs = objectMapper.readValue(jsonStr, Songs.class);
上面这行现在崩溃了,因为 ObjectMapper
无法将 en-us
字符串映射到 Locale.EN_US
。
我总是可以编辑枚举并将其定义为
public enum Locale {
EN_US("en-us"),
ES_MX("es-mx");
private String value;
Locale(String val){
value = val;
}
}
但我在某处看到了一种更聪明的方法,它将小写连字符字符串转换为大写下划线文字。你能告诉我那个解决方案吗?
我需要一个解决方案,以便 FasterXml 的 ObjectMapper
可以将字符串映射到枚举。
因为 Jackson 2.6, you can annotate your enum constants with @JsonProperty
to give them a custom name. The javadoc 状态
Starting with Jackson 2.6 this annotation may also be used to change serialization of
Enum
like so:public enum MyEnum { @JsonProperty("theFirstValue") THE_FIRST_VALUE, @JsonProperty("another_value") ANOTHER_VALUE; }
在你的情况下,你会使用
public enum Locale {
@JsonProperty("en-us") EN_US, @JsonProperty("es-mx") ES_MX
}
或者,假设所有枚举常量都遵循相同的命名模式,您可以使用 @JsonValue
。在您的枚举类型中定义一个用 @JsonValue
注释的实例方法,并使用您的命名策略实现它。例如,
@JsonValue
public String forJackson() {
return name().toLowerCase().replace('_', '-');
}
您将受益于
when use for Java enums, one additional feature is that value returned by annotated method is also considered to be the value to deserialize from, not just JSON String to serialize as. This is possible since set of Enum values is constant and it is possible to define mapping, but can not be done in general for POJO types; as such, this is not used for POJO deserialization.
它将用于序列化和反序列化。
避免使用已经出现在 JDK 中的名称来命名您的类型。 Java 已经提供了常用的 Locale
类型。考虑重命名您的 class。