如何为具有动态值的类型实现自定义GsonConverterFactor或JsonDeserializer?
例如:
如果Tags对象包含内容,则如下所示:
"tags": [
{
"content_id": "13",
"tag_id": "3",
"created": "2018-03-26 11:09:08",
"tag_name": "FICTION"
},
{
"content_id": "13",
"tag_id": "7",
"created": "2018-03-26 11:09:08",
"tag_name": "JUVENILE FICTION"
}
]
但是,如果它是空的,它将返回:
"tags": false
基本上,如果解串器将其值读为null
,我想制作标记列表false
。
答案 0 :(得分:2)
您可以像这样创建一个反序列化器
public class UserResponseDeserializer implements
JsonDeserializer<ResponseWrapper> {
@Override
public ResponseWrapper deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
if (((JsonObject) json).get("tags") instanceof JsonArray){
return new Gson().fromJson(json, ResponseArray.class);
} else {
return new Gson().fromJson(json, ResponseBoolean.class);
}
}
}
其中ResponseArray
和ResponseBoolean
延伸ResponseWrapper
如上所述here
答案 1 :(得分:1)
public class Example implements Serializable
{
@JsonProperty("tags")
private Map<String, Object> tags = new HashMap<String, Object>();
}
使用上面的类进行json解析:
Object object = tags.get("tags");
if (object instanceof JSONArray){
JSONArray jsonArray = (JSONArray) tags.get("tags");
}else {
boolean booleanValue = (boolean) tags.get("tags");
}
答案 2 :(得分:1)
类型适配器是Gson序列化/反序列化的核心,几乎可以在所有情况下提供帮助。 您只需要实现一个。
final class CollectionFalseAsNullTypeAdapterFactory
implements TypeAdapterFactory {
private static final TypeAdapterFactory instance = new CollectionFalseAsNullTypeAdapterFactory();
private CollectionFalseAsNullTypeAdapterFactory() {
}
static TypeAdapterFactory get() {
return instance;
}
@Override
public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> typeToken) {
if ( !Collection.class.isAssignableFrom(typeToken.getRawType()) ) {
return null;
}
@SuppressWarnings("unchecked")
final TypeAdapter<Collection<Object>> delegateTypeAdapter = (TypeAdapter<Collection<Object>>) gson.getDelegateAdapter(this, typeToken);
@SuppressWarnings("unchecked")
final TypeAdapter<T> typeAdapter = (TypeAdapter<T>) new CollectionFalseAsNullTypeAdapter<>(delegateTypeAdapter);
return typeAdapter;
}
private static final class CollectionFalseAsNullTypeAdapter<E>
extends TypeAdapter<Collection<E>> {
private final TypeAdapter<Collection<E>> delegateTypeAdapter;
private CollectionFalseAsNullTypeAdapter(final TypeAdapter<Collection<E>> delegateTypeAdapter) {
this.delegateTypeAdapter = delegateTypeAdapter;
}
@Override
public void write(final JsonWriter out, final Collection<E> value)
throws IOException {
delegateTypeAdapter.write(out, value);
}
@Override
public Collection<E> read(final JsonReader in)
throws IOException {
// Let's just make sure it's a boolean
if ( in.peek() == JsonToken.BOOLEAN ) {
// If yes, then just return a null skipping the boolean
in.skipValue();
return null;
}
return delegateTypeAdapter.read(in);
}
}
}
使用示例:
private static final Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd HH:mm:ss")
.registerTypeAdapterFactory(CollectionFalseAsNullTypeAdapterFactory.get())
.create();
public static void main(final String... args)
throws IOException {
for ( final String resourceName : ImmutableList.of("non-null.json", "null.json") ) {
try ( final JsonReader jsonReader = Resources.getPackageResourceJsonReader(Q50013856.class, resourceName) ) {
final Entity entity = gson.fromJson(jsonReader, Entity.class);
System.out.println(entity);
}
}
}
示例输出(假设覆盖了toString
):
实体{tags = [Tag {contentId = 13,tagId = 3,created = Mon Mar 26 11:09:08 EEST 2018,tagName = FICTION},标签{contentId = 13,tagId = 7,created = Mon Mar 26 11:09:08 EEST 2018,tagName = JUVENILE FICTION}]}
实体{tags = null}
请注意,您可以注释tags
字段更准确,而不是在全球注册工厂:
@JsonAdapter(CollectionFalseAsNullTypeAdapterFactory.class)
final List<Tag> tags = null;