java - example - Serialización Jackson: ignorar los valores vacíos(o nulo)
objectmapper java (8)
Actualmente estoy usando jackson 2.1.4 y estoy teniendo problemas para ignorar los campos cuando estoy convirtiendo un objeto en una cadena JSON.
Aquí está mi clase que actúa como el objeto a convertir:
public class JsonOperation {
public static class Request {
@JsonInclude(Include.NON_EMPTY)
String requestType;
Data data = new Data();
public static class Data {
@JsonInclude(Include.NON_EMPTY)
String username;
String email;
String password;
String birthday;
String coinsPackage;
String coins;
String transactionId;
boolean isLoggedIn;
}
}
public static class Response {
@JsonInclude(Include.NON_EMPTY)
String requestType = null;
Data data = new Data();
public static class Data {
@JsonInclude(Include.NON_EMPTY)
enum ErrorCode { ERROR_INVALID_LOGIN, ERROR_USERNAME_ALREADY_TAKEN, ERROR_EMAIL_ALREADY_TAKEN };
enum Status { ok, error };
Status status;
ErrorCode errorCode;
String expiry;
int coins;
String email;
String birthday;
String pictureUrl;
ArrayList <Performer> performer;
}
}
}
Y así es como lo convierto:
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
JsonOperation subscribe = new JsonOperation();
subscribe.request.requestType = "login";
subscribe.request.data.username = "Vincent";
subscribe.request.data.password = "test";
Writer strWriter = new StringWriter();
try {
mapper.writeValue(strWriter, subscribe.request);
} catch (JsonGenerationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JsonMappingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.d("JSON", strWriter.toString())
Aquí está el resultado:
{"data":{"birthday":null,"coins":null,"coinsPackage":null,"email":null,"username":"Vincent","password":"test","transactionId":null,"isLoggedIn":false},"requestType":"login"}
¿Cómo puedo evitar esos valores nulos? ¡Solo quiero tomar la información requerida para el propósito de "suscripción"!
Aquí está exactamente el resultado que estoy buscando:
{"data":{"username":"Vincent","password":"test"},"requestType":"login"}
¡También probé @JsonInclude (Include.NON_NULL) y puse todas mis variables a nulo, pero tampoco funcionó! ¡Gracias por su ayuda chicos!
Debe agregar import com.fasterxml.jackson.annotation.JsonInclude;
Añadir
@JsonInclude(JsonInclude.Include.NON_NULL)
encima de POJO
Si ha anidado POJO, entonces
@JsonInclude(JsonInclude.Include.NON_NULL)
necesito agregar en cada valor
NOTA: JAXRS (Jersey) maneja automáticamente este escenario 2.6 y superior.
El siguiente código puede ayudar si desea excluir el tipo booleano de la serialización:
@JsonInclude(JsonInclude.Include.NON_ABSENT)
Hace poco tuve un problema similar con la versión 2.6.6.
@JsonInclude(JsonInclude.Include.NON_NULL)
El uso de la anotación anterior en el nivel archivado o de clase no funcionaba como se esperaba. El POJO era mutable donde estaba aplicando la anotación. Cuando cambié el comportamiento del POJO para que fuera inmutable, la anotación funcionó su magia.
No estoy seguro de si la versión nueva o las versiones anteriores de esta versión tuvieron un comportamiento similar, pero para 2.6.6 ciertamente necesita tener POJO inmutables para que la anotación funcione.
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
La opción anterior mencionada en varias respuestas para establecer la inclusión de serialización en ObjectMapper directamente a nivel global también funciona, pero prefiero controlarla en clase o nivel archivado.
Por lo tanto, si desea ignorar todos los campos nulos durante la serialización JSON, utilice la anotación en el nivel de clase, pero si desea ignorar algunos campos en una clase, utilícela en esos campos específicos. De esta forma es más legible y fácil de mantener si desea cambiar el comportamiento de una respuesta específica.
O puede usar GSON [ https://code.google.com/p/google-gson/ ], donde estos campos nulos se eliminarán automáticamente.
SampleDTO.java
public class SampleDTO {
String username;
String email;
String password;
String birthday;
String coinsPackage;
String coins;
String transactionId;
boolean isLoggedIn;
// getters/setters
}
Test.java
import com.google.gson.Gson;
public class Test {
public static void main(String[] args) {
SampleDTO objSampleDTO = new SampleDTO();
Gson objGson = new Gson();
System.out.println(objGson.toJson(objSampleDTO));
}
}
SALIDA:
{"isLoggedIn":false}
Usé gson-2.2.4
Para jackson 2.x
@JsonInclude (JsonInclude.Include.NON_NULL) justo antes del campo.
También puedes establecer la opción global:
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
También puedes intentar usar
@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
si está tratando con jackson con la versión por debajo de 2+ (1.9.5) lo probé, puede usar fácilmente esta anotación sobre la clase. No especificado para los atributos, solo para la declinación de clase.
Tiene la anotación en el lugar equivocado; necesita estar en la clase, no en el campo. es decir:
@JsonInclude(Include.NON_NULL) //or Include.NON_EMPTY, if that fits your use case
public static class Request {
// ...
}
Como se señala en los comentarios, en la versión 2.x + la sintaxis para esta anotación es:
@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) // or JsonSerialize.Inclusion.NON_EMPTY
La otra opción es configurar ObjectMapper
directamente, simplemente llamando a mapper.setSerializationInclusion(Include.NON_NULL);
(para el registro, creo que la popularidad de esta respuesta es una indicación de que esta anotación debe ser aplicable campo por campo * ahem @ fasterxml *)