【问题标题】:Serialize nested class null objects with gson?用gson序列化嵌套类空对象?
【发布时间】:2012-11-19 03:21:39
【问题描述】:

我知道如何序列化空对象。但是如果我有一个对象并且在另一个对象内部是空的呢?

例如

我的第一堂课:

public class Invoice {

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

}

我的第二堂课:

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

还有更多的子类...

如果我这样做:

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

我只知道这个:

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

而不是这个:

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

应该有一种自动化的方法。总会有其他子类。因此,手动方法是行不通的。

【问题讨论】:

    标签: java object null gson


    【解决方案1】:

    我搞定了!使用 Java 反射!

    代码如下:

    1. userDefined() 检查一个类是用户定义的还是原始的,可以根据需要自定义。

      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()返回字段的setter方法。

      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. 最后,invokeSetters() 调用用户定义的对象设置方法和子类的方法!是的。

          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");
              }
            }
          }
      

    【讨论】:

      【解决方案2】:

      如果您希望adresse 具有属性,那么您需要将adresse 实例化为:

          public class Invoice implements Serializable{
              private Adresse adresse = new Adresse();
              private Double betrag;
              private Double Ust;
              private String zweck;
          }
      

      【讨论】:

      • 不。这些是 POJO 的。他们必须保持这种状态。我不允许更改它们。
      • @Delta458:然后使用 setter 方法,如果可用,例如invoice.setAdresse(addresse); 通过在序列化之前传递 new Adresse()
      • 但是生成的类和子类会很多。我不能手动做到这一点。也许有反思……但那很痛苦,哈哈
      • @Delta458 由于我对您的对象层次结构没有太多了解,因此无法发表评论。您当前的问题是由于 null 对象。 If the object itself is null, it will not have any visibility of member attributes and sub graphs.
      • 类和子类将在运行时生成......所以这种方法是不现实的,除非我使用反射......也许用jackson for java?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-05
      • 2023-04-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-30
      • 1970-01-01
      相关资源
      最近更新 更多