Administrator
发布于 2017-09-07 / 77 阅读
1

Gson中使用TypeAdapter设置默认值,如数字类型Long默认是null,但是我们需要0

Gson中使用TypeAdapter设置默认值,如数字类型Long默认是null,但是我们需要0

Gson非常好用,但在对接后台接口时,经常碰到这样的问题,就是我们前端使用了long(基本)类型,但是后台使用了Long(封装)类型,而Long默认值为null,所以接口返回的数据中有些是非必要的可能为null,这样就会导致我们解析失败,整体数据都解析出错,这是我们不期望的,有人会说我们前端也用Long类型不就好了吗?的确用Long类型解析不会出错,但是却有另一个问题,在对两个数操作时却出现空指针异常,导致应用闪退,我们总不能在所有使用到的地方都加空判断吧,所以就有了本文的解决方法。

假如我们有如下的一个Bean:

public class Entity {

    private long code;
    private String message;

    public void setCodelong code) {
        this.code = code;
    }

    public long getCode() {
        return code;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}

 

我们需要当后台返回的code为null时,默认转为0,避免程序出现异常,这时候就需要用到TypeAdapter,如下定义一个处理long的默认为0的TypeAdapter:

import android.util.Log;

import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import com.toprank.byd_b.utils.NumberUtils;

/**
 * Created by Chenguandu on 2017-9-4.
 */

public class LongTypeAdapter extends TypeAdapter {
    @Override
    public void write(JsonWriter out, Long value) {
        try {
            if (value == null){
                value = 0L;
            }
            out.value(value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public Long read(JsonReader in){
        try {
            Long value;
            if (in.peek() == JsonToken.NULL) {
                in.nextNull();
                Log.e("TypeAdapter", "null is not a number");
                return 0L;
            }
            if (in.peek() == JsonToken.BOOLEAN) {
                boolean b = in.nextBoolean();
                Log.e("TypeAdapter", b + " is not a number");
                return 0L;
            }
            if (in.peek() == JsonToken.STRING) {
                String str = in.nextString();
                if (NumberUtils.isInt(str)){
                    return Long.parseLong(str);
                } else {
                    Log.e("TypeAdapter", str + " is not a int number");
                    return 0L;
                }
            } else {
                value = in.nextLong();
                return value;
            }
        } catch (Exception e) {
            Log.e("TypeAdapter", "Not a number", e);
        }
        return 0L;
    }
}

同理int如下:

import android.util.Log;

import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import com.toprank.byd_b.utils.NumberUtils;

/**
 * Created by Chenguandu on 2017-9-4.
 */

public class IntegerTypeAdapter extends TypeAdapter {
    @Override
    public void write(JsonWriter out, Integer value) {
        try {
            if (value == null){
                value = 0;
            }
            out.value(value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public Integer read(JsonReader in) {
        try {
            Integer value;
            if (in.peek() == JsonToken.NULL) {
                in.nextNull();
                Log.e("TypeAdapter", "null is not a number");
                return 0;
            }
            if (in.peek() == JsonToken.BOOLEAN) {
                boolean b = in.nextBoolean();
                Log.e("TypeAdapter", b + " is not a number");
                return 0;
            }
            if (in.peek() == JsonToken.STRING) {
                String str = in.nextString();
                if (NumberUtils.isInt(str)){
                    return Integer.parseInt(str);
                } else {
                    Log.e("TypeAdapter", str + " is not a int number");
                    return 0;
                }
            } else {
                value = in.nextInt();
                return value;
            }
        } catch (Exception e) {
            Log.e("TypeAdapter", "Not a number", e);
        }
        return 0;
    }
}

double如下:

import android.util.Log;

import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import com.toprank.byd_b.utils.NumberUtils;

/**
 * Created by Chenguandu on 2017-9-4.
 */

public class DoubleTypeAdapter extends TypeAdapter {
    @Override
    public void write(JsonWriter out, Double value) {
        try {
            if (value == null){
                value = 0D;
            }
            out.value(value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public Double read(JsonReader in) {
        try {
            if (in.peek() == JsonToken.NULL) {
                in.nextNull();
                Log.e("TypeAdapter", "null is not a number");
                return 0D;
            }
            if (in.peek() == JsonToken.BOOLEAN) {
                boolean b = in.nextBoolean();
                Log.e("TypeAdapter", b + " is not a number");
                return 0D;
            }
            if (in.peek() == JsonToken.STRING) {
                String str = in.nextString();
                if (NumberUtils.isFloat(str)){
                    return Double.parseDouble(str);
                } else {
                    Log.e("TypeAdapter", str + " is not a number");
                    return 0D;
                }
            } else {
                Double value = in.nextDouble();
                return value == null ? 0D : value;
            }
        }catch(NumberFormatException e){
            Log.e("TypeAdapter", e.getMessage(), e);
        } catch (Exception e) {
            Log.e("TypeAdapter", e.getMessage(), e);
        }
        return 0D;
    }
}

Float如下:

import android.util.Log;

import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import com.toprank.byd_b.utils.NumberUtils;

/**
 * Created by Chenguandu on 2017-9-4.
 */

public class FloatTypeAdapter extends TypeAdapter {
    @Override
    public void write(JsonWriter out, Float value) {
        try {
            if (value == null){
                value = 0F;
            }
            out.value(value.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public Float read(JsonReader in) {
        try {
            Float value;
            if (in.peek() == JsonToken.NULL) {
                in.nextNull();
                Log.e("TypeAdapter", "null is not a number");
                return 0F;
            }
            if (in.peek() == JsonToken.BOOLEAN) {
                boolean b = in.nextBoolean();
                Log.e("TypeAdapter", b + " is not a number");
                return 0F;
            }
            if (in.peek() == JsonToken.STRING) {
                String str = in.nextString();
                if (NumberUtils.isFloat(str)){
                    return Float.parseFloat(str);
                } else {
                    Log.e("TypeAdapter", str + " is not a number");
                    return 0F;
                }
            } else {
                String str = in.nextString();
                value = Float.valueOf(str);
            }
            return value;
        } catch (Exception e) {
            Log.e("TypeAdapter", "Not a number", e);
        }
        return 0F;
    }
}


使用方法如下:

public Gson buildGson() {
        Gson  gson = new GsonBuilder()
                .registerTypeAdapter(Integer.class, new IntegerTypeAdapter())
                .registerTypeAdapter(int.class, new IntegerTypeAdapter())
                .registerTypeAdapter(Double.class, new DoubleTypeAdapter())
                .registerTypeAdapter(double.class, new DoubleTypeAdapter())
                .registerTypeAdapter(Long.class, new LongTypeAdapter())
                .registerTypeAdapter(long.class, new LongTypeAdapter())
                .registerTypeAdapter(Float.class, new FloatTypeAdapter())
                .registerTypeAdapter(float.class, new FloatTypeAdapter())
                .create();
        return gson;
    }


这样处理以后,不管理我们前端使用的是基本类型还是封装类型,也不管理接口返回的是不是null或者不是数字,都不会出现异常,如果接口返回的不是数字或是null则自动赋值为0