Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serialize nested class null objects with gson?

I know how to serialize null objects. but what if I have an objects and inside another object that is null?

e.g.

My 1st class:

public class Invoice {

   private Adresse adresse;
   private Double betrag;
   private Double Ust;
   private String zweck;

}

My 2nd class:

public class Adresse {
   private String name;
   private Ort ort;
}

And more sub-classes...

And if I do:

Gson gson = new GsonBuilder().serializeNulls().create();

I only get this:

{"adresse":null,"betrag":null,"Ust":null,"zweck":null}

instead of this:

{"adresse":{"name":null,"ort"{"plz":null,"name":null}},"betrag":null,"Ust":null,"zweck":null}

There should be an automated approach to it. There will always be other sub-classes. So a manual approach is a no-go.

like image 504
David Sonnenfeld Avatar asked Aug 04 '26 12:08

David Sonnenfeld


1 Answers

I got it working! With Java Reflection!

Here the code:

  1. userDefined() checks if a class is user defined or primitive, can be customized as you wish.

    public boolean isUserDefined(Class o) {
      if (o.isAssignableFrom(String.class)) {
        return false;
      }
      if (o.isAssignableFrom(Double.class)) {
        return false;
      }
      if (o.isAssignableFrom(Integer.class)) {
        return false;
      }
      if (o.isAssignableFrom(Boolean.class)) {
        return false;
      }
      if (o.isAssignableFrom(Short.class)) {
        return false;
      }
      if (o.isAssignableFrom(Float.class)) {
        return false;
      }
      if (o.isAssignableFrom(Long.class)) {
        return false;
      }
      return true;
    }
    
  2. getSetterMethod() returns the setter Method of a field.

    private static Method getSetterMethod(Object o, Field f) {       
        for (Method method : o.getClass().getMethods()) {
            String fieldname = "set" + f.getName();
            String methodname = method.getName().toLowerCase();
            if (fieldname.equals(methodname)) {
                return method;
            }
        }
        return null;
    }
    
  3. And finally, invokeSetters() invoke user defined object setter Methods and those of the subclasses! yea.

        private void invokeSetters(Object o) throws IllegalArgumentException, IllegalAccessException, ClassNotFoundException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        System.out.println("INVOKING THE OBJECT " + o.getClass().toString());
          for (Field f : o.getClass().getDeclaredFields()) {
            System.out.println("NOW IN THE FIELD: " + f.getName());
            f.setAccessible(true);
            Object obj = null;
            if (isUserDefined(f.getType()) && f.get(o) == null) {
                System.out.println("FIELD is USER DEFINED AND NULL");
                Class c = Class.forName(f.getType().getName());
                System.out.println("CLASS IS " + c.getName());
                obj = c.getConstructor().newInstance();
                System.out.println("GOING INSIDE " + obj.toString() + " NOW.");
                invokeSetters(obj);
            }
            if (obj != null) {
                Method setter = getSetterMethod(o, f);
                System.out.println("IM IN PARENT OBJECT " + o + " AND INVOKING METHOD " + setter.getName() + " WITH PARAMETER " + obj.toString());
                setter.invoke(o, obj);
                System.out.println("METHOD WAS INVOKED");
            }
          }
        }
    
like image 74
David Sonnenfeld Avatar answered Aug 07 '26 01:08

David Sonnenfeld



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!