Gson自定义TypeAdapter

文章讲述了如何使用Gson的TypeAdapterFactory来解决JavaBean在List字段为空时序列化为`[]`而非`null`的问题,通过自定义TypeAdapter在TypeAdapterFactory中处理空列表的序列化逻辑。
摘要由CSDN通过智能技术生成

一、Gson自定义TypeAdapter(已解决)

Gson序列化javabean,当list为null的时候,期望返回的是[]而不是null,比如

gson.toJson(response) = {“responseCode”:“404”,“responseMessage”:“message”,“recordDetail”:null}

这里的recordeDetail是一个list,期望返回的结果是

gson.toJson(response) = {“responseCode”:“404”,“responseMessage”:“message”,“recordDetail”:[]}

目前的解决方案:

自定义TypeAdapter,实现当list为empty的时候转成 [],但是现在自定义的writer方法并不执行,目前在研究啃源码,希望能找到解决方案

package hk.health.ehris.cdu.gson;

import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.List;

/**
 * @author zhangxi
 */
@Slf4j
public class EmptyListToNullTypeAdapter extends TypeAdapter<List<?>> {

    private TypeAdapter<List<?>> delegate;

    public EmptyListToNullTypeAdapter(TypeAdapter<List<?>> adapter){
        this.delegate = adapter;
    }

  	// 问题出在这里,这个自定义的方法并不执行
    @Override
    public void write(JsonWriter out, List<?> value) throws IOException {
        if (value == null || value.isEmpty()) {
            out.nullValue();  // Serialize null for empty list
        } else {
            delegate.write(out, value);
        }
    }

    @Override
    public List<?> read(JsonReader in) throws IOException {
        return delegate.read(in);
    }
}

TypeAdapterFactory(解决问题的关键)

问题场景:

有个类,其中有个字段是List,希望这个list在为空的时候,序列化的结果是[],而不是null,比如这样的一个类,在序列化的时候是这样的

public class Person {

    private String name;

    private Integer age;

    private List<Role> roleList;
    
}
//person = {"name":"楚子航","age":19,"roleList":[]}
原理:

自定义TypeAdapterFactory

为什么之前使用TypeAdapter的方式行不通?

TypeAdapter允许更精细地控制不同类型以及嵌套类型的序列化和反序列化过程,当你自定义一个TypeAdapter的时候,你是在处理单个特定类型的序列化和反序列化逻辑,而在自定义一个TypeAdapterFactory的时候,可以在更高的层面上控制对不同类型和嵌套类型的处理

问题描述

在序列化对象的时候,对象里面有个字段是List数组,当数组为空的时候,希望序列化后的结果是 “[]” 而不是"null".

解决方案

自定义 **TypeAdapterFactory,**在自定义的TypeAdapterFactory里面重写create()方法,在方法里实现自定义的TypeAdapter,可以实现对List数组的自定义操作

1. 自定义TypeAdapterFactory
public class NullListToEmptyFactory implements TypeAdapterFactory {

    public static final NullListToEmptyFactory INSTANCE = new NullListToEmptyFactory();

    private NullListToEmptyFactory(){

    }

    @Override
    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
        final Class<? super T> rawType = type.getRawType();


        //Only handle List and ArrayList,let other factories handle different types
        if (rawType != List.class && rawType != ArrayList.class){
            return null;
        }

        //delegate which handles serialization of non-null values,and deserialization
        final TypeAdapter<T> delegateAdapter = gson.getDelegateAdapter(this, type);
        return new TypeAdapter<T>() {
            @Override
            public void write(JsonWriter out, T value) throws IOException {
                log.info("自定义TypeAdapter开始处理空数组····");
                if (value == null || ((List<?>) value).isEmpty()){
                    out.beginArray().endArray();
                } else {
                    delegateAdapter.write(out,value);
                }
            }

            @Override
            public T read(JsonReader in) throws IOException {
                return delegateAdapter.read(in);
            }
        };
    }
}
2. 使用GsonBuilder注册该工厂
Gson gson = new GsonBuilder()
.serializeNulls()
.registerTypeAdapterFactory(NullListToEmptyFactory.INSTANCE)
.create();
gson.toJson(YourObject);

注册进去之后,由于Gson序列化时会首先去查找自定义的TypeAdapter,然后再去查找默认的,最后使用反射生成一个包含该类所有类型的序列化实例,进行序列化。

打印结果:

person = {“name”:“楚子航”,“age”:19,“roleList”:[]}

这里显示的是"[]",而不是“null”

TypeAdapter允许更精细地控制不同类型以及嵌套类型的序列化和反序列化过程,当你自定义一个TypeAdapter的时候,你是在处理单个特定类型的序列化和反序列化逻辑,而在自定义一个TypeAdapterFactory的时候,可以在更高的层面上控制对不同类型和嵌套类型的处理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值