Java 如何将 FasterXML\Jackson 中的布尔值序列化/反序列化为 Int?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34297506/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 15:31:07  来源:igfitidea点击:

How can I Serialize/De-serialize a Boolean Value from FasterXML\Hymanson as an Int?

javajsonspringHymansonfasterxml

提问by Raystorm

I'm writing a JSON Client for a Server that returns Booleanvalues as "0" and "1". When I try to run my JSON Client I currently get the following Exception:

我正在为服务器编写一个 JSON 客户端,该客户端将布尔值返回为“0”和“1”。当我尝试运行我的 JSON 客户端时,我目前收到以下异常:

HttpMessageNotReadableException: Could not read JSON: Can not construct instance of java.lang.Boolean from String value '0': only "true" or "false" recognized

So how can I setup FasterXML\Hymansonto correctly parse something like:

那么如何设置FasterXML\Hymanson以正确解析如下内容:

{
   "SomeServerType" : {
     "ID" : "12345",
     "ThisIsABoolean" : "0",
     "ThisIsABooleanToo" : "1"
   }
}

Sample Pojo's:

Pojo 示例:

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({"someServerType"})
public class myPojo
{
   @JsonProperty("someServerType")
   SomeServerType someServerType;

   @JsonProperty("someServerType")
   public SomeServerType getSomeServerType() { return someServerType; }

   @JsonProperty("someServertype")
   public void setSomeServerType(SomeServerType type)
   { someServerType = type; }
}


@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({"someServerType"})
public class SomeServerType 
{
   @JsonProperty("ID")
   Integer ID;

   @JsonProperty("ThisIsABoolean")
   Boolean bool;

   @JsonProperty("ThisIsABooleanToo")
   Boolean boolToo;

   @JsonProperty("ID")
   public Integer getID() { return ID; }

   @JsonProperty("ID")
   public void setID(Integer id)
   { ID = id; }

   @JsonProperty("ThisIsABoolean")
   public Boolean getThisIsABoolean() { return bool; }

   @JsonProperty("ThisIsABoolean")
   public void setThisIsABoolean(Boolean b) { bool = b; }

   @JsonProperty("ThisIsABooleanToo")
   public Boolean getThisIsABooleanToo() { return boolToo; }

   @JsonProperty("ThisIsABooleanToo")
   public void setThisIsABooleanToo(Boolean b) { boolToo = b; }
}

Rest Client Line
Note 1:This is using Spring 3.2
Note 2:toJSONString() - is a helper method that uses Hymanson to Serialize my Parameters Object
Note 3:The Exception happens on Reading INthe result object

Rest Client Line
Note 1:这是使用 Spring 3.2
Note 2:toJSONString() - 是一种使用 Hymanson 序列化我的参数对象的辅助方法
注意 3:读取结果对象时发生异常

DocInfoResponse result = restTemplate.getForObject(docInfoURI.toString()
                                  + "/?input={input}",
                                  DocInfoResponse.class,
                                  toJSONString(params));

采纳答案by callmepills

As Paulo Pedroso's answer mentioned and referenced, you will need to roll your own custom JsonSerializerand JsonDeserializer. Once created, you will need to add the @JsonSerializeand @JsonDeserializeannotations to your property; specifying the class to use for each.

正如保罗·佩德罗索 (Paulo Pedroso) 的回答所提到和引用的,您将需要推出自己的自定义JsonSerializerJsonDeserializer. 创建后,您需要将@JsonSerialize@JsonDeserialize注释添加到您的属性中;指定用于每个的类。

I have provided a small (hopefully straightforward) example below. Neither the serializer nor deserializer implementations are super robust but this should get you started.

我在下面提供了一个小的(希望是简单的)示例。序列化器和反序列化器的实现都不是超级健壮的,但这应该会让你开始。

public static class SimplePojo {

    @JsonProperty
    @JsonSerialize(using=NumericBooleanSerializer.class)
    @JsonDeserialize(using=NumericBooleanDeserializer.class)
    Boolean bool;
}

public static class NumericBooleanSerializer extends JsonSerializer<Boolean> {

    @Override
    public void serialize(Boolean bool, JsonGenerator generator, SerializerProvider provider) throws IOException, JsonProcessingException {
        generator.writeString(bool ? "1" : "0");
    }   
}

public static class NumericBooleanDeserializer extends JsonDeserializer<Boolean> {

    @Override
    public Boolean deserialize(JsonParser parser, DeserializationContext context) throws IOException, JsonProcessingException {
        return !"0".equals(parser.getText());
    }       
}

@Test
public void readAndWrite() throws JsonParseException, JsonMappingException, IOException {
    ObjectMapper mapper = new ObjectMapper();

    // read it
    SimplePojo sp = mapper.readValue("{\"bool\":\"0\"}", SimplePojo.class);
    assertThat(sp.bool, is(false));

    // write it
    StringWriter writer = new StringWriter();
    mapper.writeValue(writer, sp);
    assertThat(writer.toString(), is("{\"bool\":\"0\"}"));
}

回答by StaxMan

Instead of custom deserializer, you could also simply have a setter like:

除了自定义解串器,您还可以简单地使用一个 setter,例如:

public void setThisIsABoolean(String str) {
  if ("0".equals(str)) {
    bool = false;
  } else {
    bool = true;
  }
}

since your method can claim different type than what you use internally.

因为您的方法可以声明与您内部使用的类型不同的类型。

And if you have to support both Booleanand String, you can indicate value is an Object, and check what you might get.

如果您必须同时支持Booleanand String,您可以指定 value 是 an Object,并检查您可能会得到什么。

It should even be possible to have different type for getter method (Boolean) and setter (Stringor Object).

它甚至应该有可能具有不同类型的吸气剂的方法(Boolean)和setter(StringObject)。