Search code examples
spring-bootjackson2jackson-databind

NPE from Jackson trying to serializing a field that does not exists?


Here is my simple bean

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Foo {

    private String firstName;
    private String lastName;

    public String getFullName(){
     return firstName + lastName;
    }

}

when this object gets serialized in Spring-boot controller with Jackson, I get the following error

j.l.NullPointerException: null
   com.example.foobar.foo.getFullName(Foo.java:28)
  s.r.NativeMethodAccessorImpl.invoke0(NativeMethodAccessorImpl.java)
  s.r.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  s.r.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  j.l.reflect.Method.invoke(Method.java:498)
  c.f.j.d.s.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:653)
  c.f.j.d.s.s.BeanSerializerBase.serializeFields(BeanSerializerBase.java:690)..
  28 common frames omitted\nWrapped by: c.f.j.d.JsonMappingException: (was java.lang.NullPointerException) 
  (through reference chain: com.example.foobar.foo[\"fullName\"])
   c.f.j.d.JsonMappingException.wrapWithPath(JsonMappingException.java:379)
  c.f.j.d.JsonMappingException.wrapWithPath(JsonMappingException.java:339)
  c.f.j.d.s.s.StdSerializer.wrapAndThrow(StdSerializer.java:343)
  c.f.j.d.s.s.BeanSerializerBase.serializeFields(BeanSerializerBase.java:698)
  c.f.j.d.s.BeanSerializer.serialize(BeanSerializer.java:155)
  c.f.j.d.s.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:292)
  c.f.j.d.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1419)
  c.f.j.d.ObjectWriter.writeValue(ObjectWriter.java:940)
  o.s.h.c.j.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:267)...
  23 common frames omitted\nWrapped by: o.s.h.c.HttpMessageNotWritableException: Could not write content: (was java.lang.NullPointerException) (through reference chain: com.example.foobar.foo[\"fullName\"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: com.example.foobar.foo[\"fullName\"])
                                                                                                                                                o.s.h.c.j.AbstractJackson2HttpMessageConverter.writeInternal(AbstractJackson2HttpMessageConverter.java:274 ..."

Here is the requestBody that I sent

{"firstName": "foo",
"lastName: null
}

Is Jackson trying to serialize fullName property ? but I have no such field declared. is this expected behavior? I am unable to find documentation that supports this behavior.

Thanks


Solution

  • Your guess is right, Jackson is trying to find the field name by its getter method, which it cannot find. And hence NPE.

    Different solutions

    1. use @JsonIgnore on the getFullName method.
    2. you can disable this feature by setting this property in spring boot application.properties file

      spring.jackson.mapper.use-getters-as-setters=false

    3. If you wish to do it with the java code (If not using spring boot), you can do it with a bean declaration like this

      @Bean
      public Jackson2ObjectMapperBuilder objectMapperBuilder() {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.featuresToDisable(MapperFeature.USE_GETTERS_AS_SETTERS);
        return builder;
      }