serialize creator java json spring jackson fasterxml

creator - objectmapper java



¿Cómo puedo serializar/des-serializar un valor booleano de FasterXML / Jackson como un Int? (2)

Estoy escribiendo un cliente JSON para un servidor que devuelve valores booleanos como "0" y "1". Cuando intento ejecutar mi cliente JSON, actualmente obtengo la siguiente excepción:

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

Entonces, ¿cómo puedo configurar FasterXML / Jackson para analizar correctamente algo como:

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

Muestra de Pojo''s:

@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; } }

Línea de cliente de descanso
Nota 1: Esto está utilizando Spring 3.2
Nota 2: toJSONString () - es un método auxiliar que usa Jackson para serializar mi objeto de parámetros
Nota 3: La excepción ocurre al leer en el objeto de resultado

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


Como se mencionó y mencionó la respuesta de Paulo Pedroso, deberá lanzar su propio JsonSerializer y JsonDeserializer . Una vez creados, deberá agregar las anotaciones @JsonSerialize y @JsonDeserialize a su propiedad; especificando la clase a utilizar para cada uno.

He proporcionado un pequeño ejemplo (con suerte, sencillo) a continuación. Ni las implementaciones de serializador ni de deserializador son súper robustas, pero esto debería comenzar.

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/"}")); }


En lugar de deserializador personalizado, también podría tener simplemente un setter como:

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

ya que su método puede reclamar un tipo diferente al que usa internamente.

Y si tiene que admitir tanto Boolean como String , puede indicar que el valor es un Object y verificar lo que podría obtener.

Incluso debería ser posible tener un tipo diferente para el método getter ( Boolean ) y setter ( String o Object ).