【问题标题】:Customizing enum constant names with Jackson使用 Jackson 自定义枚举常量名称
【发布时间】:2017-01-06 22:42:13
【问题描述】:

我有一个枚举定义为

public enum Locale {
  EN_US, ES_MX
}

但是,这些区域设置为小写字符串,连字符为en-uses-mx 在数据中。

有没有办法将这些小写字符串映射到相应的枚举常量?喜欢en-usEN_US

编辑 让我提供更多信息。我有以下类的对象。

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
    }
  ]
}

我定义了另一个类。

public class Songs {
  private Set<Song> songs;
}

我使用 FasterXml 的 ObjectMapper 将 JSON 加载为 Songs 类的对象。

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 可以将字符串映射到枚举。

【问题讨论】:

  • @jhamon:这不是重复的。我在调用已定义枚举的特定方法时没有灵活性。我不知道杰克逊的 ObjectMapper 会调用什么方法。它可能只适用于构造函数。

标签: java enums jackson fasterxml


【解决方案1】:

由于Jackson 2.6,您可以使用@JsonProperty 注释您的枚举常量,以给它们一个自定义名称。 javadoc 状态

从 Jackson 2.6 开始,这个注解也可以用来改变 Enum 的序列化如下:

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('_', '-');
}

你会得到很好的好处

当用于 Java 枚举时,另一个特性是返回值 by annotated method 也被认为是要反序列化的值 从,而不仅仅是要序列化为的 JSON 字符串。这是可能的,因为设置 枚举值的数量是常数,可以定义映射,但是 一般不能对 POJO 类型进行;因此,这不被使用 用于 POJO 反序列化。

它将用于序列化和反序列化。


避免使用已出现在 JDK 中的名称来命名您的类型。 Java 已经提供了一个常用的Locale 类型。考虑重命名您的班级。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-27
    • 2013-01-09
    相关资源
    最近更新 更多