java Gson - 将任何空值序列化为空字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26041726/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Gson - Serialize any null value to empty string
提问by anony115511
I'm using gson to serialize some object. I have a requirement that any null field should be treated as an empty string, independent on the variable being a string, double or a pojo.
我正在使用 gson 来序列化某个对象。我有一个要求,任何空字段都应该被视为空字符串,独立于变量是字符串、double 或 pojo。
I tried to create a custom serializer for Object and simply return a new JsonPrimitive("") for the null valued objects, but the problem is how to handle the non-null valued objects without the use of "instanceof" or "getClass" and handling every single type.
我试图为 Object 创建一个自定义序列化程序,并简单地为空值对象返回一个新的 JsonPrimitive(""),但问题是如何在不使用“instanceof”或“getClass”的情况下处理非空值对象和处理每一种类型。
Any thoughts on how to do this is appreciated.
任何关于如何做到这一点的想法表示赞赏。
回答by tmarwen
This can be done using a custom TypeAdaptor
for your model Object
.
这可以使用自定义TypeAdaptor
模型来完成Object
。
You can iterate over the object field using reflection and whenever a field is null
, set the value in the json representation to an empty string whenever you cross a null field.
您可以使用反射遍历对象字段,并且每当字段为 时null
,只要跨越空字段,就将 json 表示中的值设置为空字符串。
This would absolutely be hard to maintain and should be done with some risks as @Sotirios Delimanolis stated, What if the corresponding reference is not a String, how are you going to intending to handle it back and forth?
正如@Sotirios Delimanolis 所说,这绝对难以维护,并且应该冒一些风险,如果相应的引用不是 String怎么办,您打算如何来回处理它?
- Here is a bean structure just used to showcase the situation:
- 这是一个用于展示情况的 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";
}
}
}
- Here is the
TypeAdapter
implementation which set anynull
value to and empty ""String
:
- 这是
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;
}
}
- Now a simple straightforward
main
method to add the adapter toGson
:
- 现在有一个简单直接的
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);
}
}
This would result in below output:
这将导致以下输出:
{"id":"16","name":"entity","socialNumber":"123","innerEntity":"whateverValue"}
{"id":"0","name":"","socialNumber":"","innerEntity":""}
Note that whatever the object is of type, its value is set to "" in the marshalled json string.
请注意,无论对象是什么类型,其值都在编组的 json 字符串中设置为 ""。