Gson - 将任何空值序列化为空字符串

时间:2014-09-25 14:55:29

标签: java gson

我使用gson序列化一些对象。我要求任何空字段都应该被视为空字符串,独立于变量是字符串,双精度或极化。

我尝试为Object创建一个自定义序列化程序,并简单地为null值对象返回一个新的JsonPrimitive(""),但问题是如何在不使用的情况下处理非null值对象" instanceof"或" getClass"并处理每一种类型。

对于如何做到这一点的任何想法都表示赞赏。

2 个答案:

答案 0 :(得分:4)

可以使用模型TypeAdaptor的自定义Object来完成此操作。

您可以使用反射迭代对象字段,每当字段为null时,只要跨过空字段,就将json表示中的值设置为空字符串。

这绝对难以维护,应该有一些风险,如@Sotirios Delimanolis所说,如果相应的引用不是String 怎么办,你打算如何处理它? ??

  • 这是一个用于展示情况的bean结构:
public class MyEntity
{
  private int id;
  private String name;
  private Long socialNumber;
  private MyInnerEntity innerEntity;

  public MyEntity(int id, String name, Long socialNumber, MyInnerEntity innerEntity)
  {
    this.id = id;
    this.name = name;
    this.socialNumber = socialNumber;
    this.innerEntity = innerEntity;
  }

  public int getId()
  {
    return id;
  }

  public String getName()
  {
    return name;
  }

  public Long getSocialNumber()
  {
    return socialNumber;
  }

  public MyInnerEntity getInnerEntity()
  {
    return innerEntity;
  }

  public static class MyInnerEntity {
    @Override
    public String toString()
    {
      return "whateverValue";
    }
  }
}
  • 以下是TypeAdapter实施,它将null值设置为空并“” String
public class GenericAdapter extends TypeAdapter<Object>
{
  @Override
  public void write(JsonWriter jsonWriter, Object o) throws IOException
  {
    jsonWriter.beginObject();
    for (Field field : o.getClass().getDeclaredFields())
    {
      Object fieldValue = runGetter(field, o);
      jsonWriter.name(field.getName());
      if (fieldValue == null)
      {
        jsonWriter.value("");
      }
      else {
        jsonWriter.value(fieldValue.toString());
      }
    }
    jsonWriter.endObject();
  }

  @Override
  public Object read(JsonReader jsonReader) throws IOException
  {
    /* Don't forget to add implementation here to have your Object back alive :) */
    return null;
  }

  /**
   * A generic field accessor runner.
   * Run the right getter on the field to get its value.
   * @param field
   * @param o {@code Object}
   * @return
   */
  public static Object runGetter(Field field, Object o)
  {
    // MZ: Find the correct method
    for (Method method : o.getClass().getMethods())
    {
      if ((method.getName().startsWith("get")) && (method.getName().length() == (field.getName().length() + 3)))
      {
        if (method.getName().toLowerCase().endsWith(field.getName().toLowerCase()))
        {
          try
          {
            return method.invoke(o);
          }
          catch (IllegalAccessException e)
          { }
          catch (InvocationTargetException e)
          { }
        }
      }
    }
    return null;
  }
}
  • 现在可以使用简单明了的main方法将适配器添加到Gson
public class Test
{
  public static void main(String[] args)
  {
    Gson gson = new GsonBuilder().registerTypeAdapter(MyEntity.class, new GenericAdapter()).create();
    Object entity = new MyEntity(16, "entity", (long)123, new MyEntity.MyInnerEntity());
    String json = gson.toJson(entity);
    System.out.println(json);

    Object entity2 = new MyEntity(0, null, null, null);
    json = gson.toJson(entity2);
    System.out.println(json);
  }
}

这会导致输出低于:

{"id":"16","name":"entity","socialNumber":"123","innerEntity":"whateverValue"}
{"id":"0","name":"","socialNumber":"","innerEntity":""}

请注意,无论对象是什么类型,其值在编组的json字符串中都设置为“”。

答案 1 :(得分:0)