1

Hi I have the following object mapper:

public <T> T convertJSONtoPOJO(String inputJSON,
                               Class<T> valueType) throws Exception {
    try {
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);
        return objectMapper.readValue(inputJSON, valueType);
    } catch (Exception exception) { 
        //my exception which doesnt matter now
    }
}

And incoming JSON:

{
    "propertyA": "1",
    "propertyB": null, 
}

And POJO:

@FieldDefaults(level = AccessLevel.PRIVATE)
@Data
public class MyClazz {
    String propertyA;
    String propertyB;
    String propertyC;
}

By default @JsonProperty required is set to false on all of them.

Now while deserializing I want to obtain POJO which does NOT include: a) non-required variables if they do NOT occur in JSON b) variables which have null value.

Currently my code does NOT fail, it simply gives me the following POJO:

propertyA = 1
propertyB = null
propertyC = null

But I want to obtain POJO with only:

propertyA = 1
ICT
  • 25
  • 6
  • 1
    Given that `propertyB` and `propertyC` are `int` fields, I'd expect them to be 0 rather than null. But fundamentally you've got a class - you can't change which fields are present in the class at execution time. What would you expect to happen to any code that refers to `propertyB` or `propertyC`? – Jon Skeet Sep 20 '22 at 11:25
  • Oh right, sorry, in real code I have String type - Ive retyped it cause I cannot post real code. I would expect some exception to occur but I dont know the name :) – ICT Sep 20 '22 at 11:31
  • You don't have to post *the* real code, but it's a lot easier to help if you provide *representative* code. Fundamentally it sounds like you want something more dynamic than a POJO - maybe just deserialize to a map? – Jon Skeet Sep 20 '22 at 12:00
  • What I am checking is: A) my model in Swagger has not all properties required B) In my cucumber test I have method checking whether obtained model has no nul or empty fields C) The reason why I want not to include nonrequired properties in POJO because I do NOT require them to occur and if they are missing I want them to be also missing from my POJO to be able to check whethe rest of properties is not null :) – ICT Sep 20 '22 at 12:01
  • Okay sorry Ive edited my post to have Strings instead of ints – ICT Sep 20 '22 at 12:02
  • But you still haven't really clearly said what you're trying to achieve. Classes don't change at execution time. They're compiled, and the fields that are there, are there. Without knowing what you're trying to achieve in more detail, no-one will be able to help you. – Jon Skeet Sep 20 '22 at 12:19
  • I want to check whether my response model .hasNoNullFieldsOrProperties but only for those properties which are not required. Actually you did help me - I believe I went too far with it, I should abb tag @NotNull and a BeanValidator to my object mapper and assert that at casting stage, not later on. – ICT Sep 20 '22 at 12:24
  • And why shouldn't it include `null`? You haven't told Jackson to exclude those? See https://stackoverflow.com/questions/11757487/how-to-tell-jackson-to-ignore-a-field-during-serialization-if-its-value-is-null on how to configure jackson as such. For the incoming part use java bean validation with `@NotNull` and or `@NotEmpty`. – M. Deinum Sep 20 '22 at 13:35

2 Answers2

1

If any of your fields are not required, you have to check them whether they are null or else, while using them. Because your class is represented by all the fields you define for it, and there is no way to ignore those fields with null values.

It's possible while serializing and converting to json, but not in deserializing.

  • Okay thank you I get it now, I wanted to do the check too late :) I would score up but I dont have 15 points reputation – ICT Sep 20 '22 at 12:43
1

One solution is create your own anotation @RequiredOnLoad

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface RequiredOnLoad { 
}

And your own load json, some like this:

//new function with check required fields
public <T> T myConvertJSONtoPOJO(String inputJSON,
                               Class<T> valueType) throws Exception {
   T pojo  = convertJSONtoPOJO(inputJSON,valueType);

   Field[] allFields = Person.class.getDeclaredFields();

   for (Field field : allFields)
   {
       if(field.isAnnotationPresent(RequiredOnLoad.class))
       {
          field.setAccessible(true);//to access private fields
          Object value = field.get(pojo);
          if (value == null ) 
          {
            throw new Exception("Field is required on load!");
          }
       } 
   }

   return pojo;
}
//old function without check
public <T> T convertJSONtoPOJO(String inputJSON,
{
...

Of course, in your POJO you need put the annotation when you field is required in load time