Establecer valores predeterminados en campos nulos cuando se asigna con Jackson


Estoy tratando de mapear algunos objetos JSON a objetos Java con Jackson. Algunos de los campos en el objeto JSON son obligatorios (que puedo marcar con @NotNull) y algunos son opcionales.

Después de la asignación con Jackson, todos los campos que no están establecidos en el objeto JSON tendrán un valor null en Java. ¿Hay una anotación similar a @NotNull que pueda decirle a Jackson que establezca un valor predeterminado para un miembro de la clase Java, en caso de que sea null?

Editar: Para hacer la pregunta más clara aquí hay algunos ejemplo de código.

El objeto Java:

class JavaObject {
    @NotNull
    public String notNullMember;

    @DefaultValue("Value")
    public String optionalMember;
}

El objeto JSON puede ser:

{
    "notNullMember" : "notNull"
}

O:

{
    "notNullMember" : "notNull",
    "optionalMember" : "optional"
}

Las @DefaultValue anotaciones son solo para mostrar lo que estoy pidiendo. No es una anotación real. Si el objeto JSON es como en el primer ejemplo, quiero que el valor de optionalMember sea "Value" y no null. ¿Hay alguna anotación que haga tal cosa?

Author: gookman, 2013-09-14

5 answers

No hay ninguna anotación para establecer el valor por defecto.
Puede establecer el valor predeterminado solo en el nivel de clase java:

public class JavaObject 
{
    public String notNullMember;

    public String optionalMember = "Value";
}
 44
Author: Ilya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-14 21:54:29

Solo una solución propuesta mantiene el default-value cuando some-value:null se estableció explícitamente (la legibilidad del POJO se pierde allí y es torpe)

Así es como uno puede mantener el default-value y nunca ponerlo en null

@JsonProperty("some-value")
public String someValue = "default-value";

@JsonSetter("some-value")
public void setSomeValue(String s) {
    if (s != null) { 
        someValue = s; 
    }
}
 7
Author: Sergey Voitovich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-25 11:46:28

Parece que la solución es establecer el valor de las propiedades dentro del constructor predeterminado. Así que en este caso la clase java es:

class JavaObject {

    public JavaObject() {

        optionalMember = "Value";
    }

    @NotNull
    public String notNullMember;

    public String optionalMember;
}

Después de la asignación con Jackson, si el optionalMember falta en el JSON, su valor en la clase Java es "Value".

Sin embargo, todavía estoy interesado en saber si hay una solución con anotaciones y sin el constructor predeterminado.

 4
Author: gookman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-14 21:15:33

Haga que el miembro sea privado y agregue un par setter/getter. En su setter, si es null, establezca el valor predeterminado en su lugar. Además, he mostrado el fragmento con el getter también devolviendo un valor predeterminado cuando el valor interno es null.

class JavaObject {
    private static final String DEFAULT="Default Value";

    public JavaObject() {
    }

    @NotNull
    private String notNullMember;
    public void setNotNullMember(String value){
            if (value==null) { notNullMember=DEFAULT; return; }
            notNullMember=value;
            return;
    }

    public String getNotNullMember(){
            if (notNullMember==null) { return DEFAULT;}
            return notNullMember;
    }

    public String optionalMember;
}
 2
Author: Michael Joyner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-27 18:17:34

Tuve un problema similar, pero en mi caso el valor por defecto estaba en la base de datos. A continuación se muestra la solución para eso:

 @Configuration
 public class AppConfiguration {
 @Autowired
 private AppConfigDao appConfigDao;

 @Bean
 public Jackson2ObjectMapperBuilder builder() {
   Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder()
       .deserializerByType(SomeDto.class, 
 new SomeDtoJsonDeserializer(appConfigDao.findDefaultValue()));
   return builder;
 }

Luego en SomeDtoJsonDeserializer use ObjectMapper para deserializar el json y establecer el valor predeterminado si su campo/objeto es null.

 0
Author: Adrian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-26 15:12:48