使用Jackson

时间:2017-01-06 22:42:14

标签: java enums jackson fasterxml

我将枚举定义为

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

1 个答案:

答案 0 :(得分:10)

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枚举时,一个额外的功能是返回值   通过注释方法也被认为是反序列化的值   来自,而不仅仅是要序列化的JSON字符串。这是可能的,因为设置   Enum值是常量,可以定义映射,但是   POJO类型一般不能做;因此,这不使用   用于POJO反序列化。

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

<子> 避免使用已经出现在JDK中的名称来命名类型。 Java已经提供了常用的Locale类型。考虑重命名你的课程。