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
).