我使用gson序列化一些对象。我要求任何空字段都应该被视为空字符串,独立于变量是字符串,双精度或极化。
我尝试为Object创建一个自定义序列化程序,并简单地为null值对象返回一个新的JsonPrimitive(""),但问题是如何在不使用的情况下处理非null值对象" instanceof"或" getClass"并处理每一种类型。
对于如何做到这一点的任何想法都表示赞赏。
答案 0 :(得分:4)
可以使用模型TypeAdaptor
的自定义Object
来完成此操作。
您可以使用反射迭代对象字段,每当字段为null
时,只要跨过空字段,就将json表示中的值设置为空字符串。
这绝对难以维护,应该有一些风险,如@Sotirios Delimanolis所说,如果相应的引用不是String 怎么办,你打算如何处理它? ??
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)