我正在使用Gson和Retrofit,我有一个案例需要序列化一个空字段,但是我无法打开Gson的全局serializeNulls()标志,因为它会破坏我的其余代码。有谁知道如何做到这一点?
这是我尝试过的:
我也找不到添加到序列化json的方法,因为它全部发生在Retrofit中。
答案 0 :(得分:1)
我通过在TypeAdapter.write()中设置setSerializeNulls(true)并将原始值恢复为JsonWriter解决了这个问题:
public class NullableDoubleAdapter extends TypeAdapter<NullableDouble> {
@Override
public void write(final JsonWriter out, final NullableDouble value) throws IOException {
if (value == null) {
boolean serializeNulls = out.getSerializeNulls();
out.setSerializeNulls(true);
out.nullValue();
out.setSerializeNulls(serializeNulls);
} else {
out.value(value.getValue());
}
}
...
答案 1 :(得分:0)
这是Andriy解决方案的扩展,它不仅适用于NullableDouble
,而且允许一般包装任何类型。与普通serializeNulls()
相比,它的缺点是它需要创建GsonForceNull
实例作为包装并在整个Java代码中访问value
内部(尽管合适的getter / setter实现可以隐藏该细节)
import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
// Forces Gson to output `null` in case the value is null, rather than omitting the field altogether.
public class GsonForceNull<V> {
public V value;
public GsonForceNull() {
}
public GsonForceNull(V value) {
this.value = value;
}
static class ForceNullTypeAdapterFactory implements TypeAdapterFactory {
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
if (type.getRawType() != GsonForceNull.class) return null;
//noinspection unchecked
return this.createInternal(gson,
(TypeToken) TypeToken.get(((ParameterizedType) type.getType()).getActualTypeArguments()[0]));
}
private <V> TypeAdapter<GsonForceNull<V>> createInternal(Gson gson, TypeToken<V> innerType) {
final TypeAdapter<V> delegate = gson.getDelegateAdapter(this, innerType);
return new TypeAdapter<GsonForceNull<V>>() {
@Override
public void write(JsonWriter out, GsonForceNull<V> value) throws IOException {
V innerValue = value == null ? null : value.value;
if (innerValue == null && !out.getSerializeNulls()) {
out.setSerializeNulls(true);
out.nullValue();
out.setSerializeNulls(false);
} else {
delegate.write(out, innerValue);
}
}
@Override
public GsonForceNull<V> read(JsonReader in) throws IOException {
return new GsonForceNull<>(delegate.read(in));
}
};
}
}
}
使用示例:
gsonBuilder.registerTypeAdapterFactory(new GsonForceNull.ForceNullTypeAdapterFactory());
class MyExampleRequestClass {
private final GsonForceNull<Long> someField = new GsonForceNull<>();
// getter/setter
}