如何将多个JsonProperty映射到单个变量?

时间:2018-05-14 06:44:08

标签: java jackson

我有一个PrintType枚举,我想将空字符串反序列化为DEFAULT类型;

@JsonProperty("default", "")
DEFAULT

有没有办法将多个JsonProperty映射到单个变量?

My PrintType enum;

public enum PrintType{

    @JsonProperty("default")
    DEFAULT,


    ....

}

1 个答案:

答案 0 :(得分:1)

首先,请注意JsonProperty用于表示属性的名称,而不是其值。在此示例中,DEFAULT是枚举的元素,而不是其属性/字段/方法,因此此注释不合适。

要从多个可能的值反序列化枚举元素,您需要创建一个将执行映射的简单JsonDeserializer。例如:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;

import java.io.IOException;

public class PrintTypeDeserializer extends JsonDeserializer<PrintType> {

  private static final Set<String> DEFAULT_VALUES = new HashSet<>(Arrays.asList("", "default"));

  @Override
  public PrintType deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
    final String value = jsonParser.getValueAsString();
    if (DEFAULT_VALUES.contains(value)) {
      return PrintType.DEFAULT;
    }
    return PrintType.valueOf(value);
  }

}

要使用此反序列化器,请在PrintType字段上声明它以进行反序列化:

public class MyObj {

  @JsonProperty("print_type")
  @JsonDeserialize(using = PrintTypeDeserializer.class)
  private PrintType printType;

}

(但如果PrintType出现在不同的对象中,则需要复制)

或者在相应的ObjectMapper

中注册反序列化器
private static ObjectMapper initObjectMapper() {
  final ObjectMapper mapper = new ObjectMapper();
  final SimpleModule module = new SimpleModule();
  module.addDeserializer(PrintType.class, new PrintTypeDeserializer());
  mapper.registerModule(module);
  return mapper;
}

现在,一个简短的测试用例:

public enum PrintType {

  DEFAULT, TYPE_A, TYPE_B;

}

@Test
public void deserializeEnum() {
  final List<String> jsons = Arrays.asList(
      "{ \"print_type\": null }",
      "{ \"print_type\": \"\" }",
      "{ \"print_type\": \"default\" }",
      "{ \"print_type\": \"DEFAULT\" }",
      "{ \"print_type\": \"TYPE_A\" }",
      "{ \"print_type\": \"TYPE_B\" }"
  );

  final ObjectMapper mapper = initObjectMapper();

  jsons.stream().forEach(json -> {
    try {
      System.out.println(mapper.readValue(json, MyObj.class));
    } catch (IOException e) {
      throw new IllegalStateException(e);
    }
  });

}

// output:
//  MyObj(printType=null)
//  MyObj(printType=DEFAULT)
//  MyObj(printType=DEFAULT)
//  MyObj(printType=DEFAULT)
//  MyObj(printType=TYPE_A)
//  MyObj(printType=TYPE_B)