Gson的使用和注解

試著忘記壹切 提交于 2020-04-08 12:11:08

目前比较流行的处理json数据的工具是Jackson和Fastjson,只有少数的公司使用Gson(一些公司对外部插件的安全性要求问题,如某些银行),这里对Gson的使用作个记录。

1、引进Gson jar包

<dependency>
  <groupId>com.google.code.gson</groupId>
  <artifactId>gson</artifactId>
  <version>2.8.6</version>
</dependency>

2、Gson工具类

    Q: 直接Gson gson = new Gson;    也是可以使用的,那为什么要自己写Gson工具类呢?
    A: 写工具类是为了统一处理一些特殊情况,如null值的处理等。

import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
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.JsonToken;
import com.google.gson.stream.JsonWriter;

public final class GsonUtils {

    private static String DATE_TIME_PATTERN_DEFAULT = "yyyy-MM-dd HH:mm:ss";

    private static ThreadLocal<DateFormat> dateFormat = new ThreadLocal<DateFormat>() {
        @Override
        protected DateFormat initialValue() {
            return new SimpleDateFormat(DATE_TIME_PATTERN_DEFAULT);
        }
    };

    private static TypeAdapter<BigDecimal> decimalTypeAdapter = new TypeAdapter<BigDecimal>() {
        @Override
        public BigDecimal read(JsonReader in) throws IOException {
            try {
                if (in.peek() == JsonToken.NULL) {
                    in.nextNull();
                    return BigDecimal.ZERO;
                }
                return BigDecimal.valueOf(in.nextDouble());
            } catch (NumberFormatException e) {
                return BigDecimal.ZERO;
            }
        }
        @Override
        public void write(JsonWriter out, BigDecimal value) throws IOException {
            out.value(value);
        }
    };
    private static TypeAdapter<BigInteger> bigIntegerTypeAdapter = new TypeAdapter<BigInteger>() {
        @Override
        public BigInteger read(JsonReader in) throws IOException {
            try {
                if (in.peek() == JsonToken.NULL) {
                    in.nextNull();
                    return BigInteger.ZERO;
                }
                return BigInteger.valueOf(in.nextLong());
            } catch (NumberFormatException e) {
                return BigInteger.ZERO;
            }
        }
        @Override
        public void write(JsonWriter out, BigInteger value) throws IOException {
            out.value(value);
        }
    };
    private static TypeAdapter<Double> doubleTypeAdapter = new TypeAdapter<Double>() {
        @Override
        public Double read(JsonReader in) throws IOException {
            try {
                if (in.peek() == JsonToken.NULL) {
                    in.nextNull();
                    return 0d;
                }
                return in.nextDouble();
            } catch (NumberFormatException e) {
                return 0d;
            }
        }
        @Override
        public void write(JsonWriter out, Double value) throws IOException {
            out.value(value);
        }
    };
    private static TypeAdapter<Float> floatTypeAdapter = new TypeAdapter<Float>() {
        @Override
        public Float read(JsonReader in) throws IOException {
            try {
                if (in.peek() == JsonToken.NULL) {
                    in.nextNull();
                    return 0f;
                }
                return Float.parseFloat(String.valueOf(in.nextDouble()));
            } catch (NumberFormatException e) {
                return 0f;
            }
        }
        @Override
        public void write(JsonWriter out, Float value) throws IOException {
            out.value(value);
        }
    };
    private static TypeAdapter<Long> longTypeAdapter = new TypeAdapter<Long>() {
        @Override
        public Long read(JsonReader in) throws IOException {
            try {
                if (in.peek() == JsonToken.NULL) {
                    in.nextNull();
                    return 0L;
                }
                return in.nextLong();
            } catch (NumberFormatException e) {
                return 0L;
            }
        }
        @Override
        public void write(JsonWriter out, Long value) throws IOException {
            out.value(value);
        }
    };
    private static TypeAdapter<Integer> integerTypeAdapter = new TypeAdapter<Integer>() {
        @Override
        public Integer read(JsonReader in) throws IOException {
            try {
                if (in.peek() == JsonToken.NULL) {
                    in.nextNull();
                    return 0;
                }
                return in.nextInt();
            } catch (NumberFormatException e) {
                return 0;
            }
        }
        @Override
        public void write(JsonWriter out, Integer value) throws IOException {
            out.value(value);
        }
    };
    private static TypeAdapter<Boolean> booleanTypeAdapter = new TypeAdapter<Boolean>() {
        @Override
        public Boolean read(JsonReader in) throws IOException {
            try {
                if (in.peek() == JsonToken.NULL) {
                    in.nextNull();
                    return Boolean.FALSE;
                }
                return in.nextBoolean();
            } catch (IllegalArgumentException e) {
                return Boolean.FALSE;
            }
        }
        @Override
        public void write(JsonWriter out, Boolean value) throws IOException {
            out.value(value);
        }
    };
    private static TypeAdapter<Date> dateTypeAdapter = new TypeAdapter<Date>() {
        @Override
        public Date read(JsonReader in) throws IOException {
            try {
                if (in.peek() == JsonToken.NULL) {
                    in.nextNull();
                    return null;
                }
                return dateFormat.get().parse(in.nextString());
            } catch (IllegalArgumentException | ParseException e) {
                return null;
            }
        }
        @Override
        public void write(JsonWriter out, Date value) throws IOException {
            out.value(dateFormat.get().format(value));
        }
    };
    static class StringNullAdapter extends TypeAdapter<String> {
        @Override
        public String read(JsonReader reader) throws IOException {
            if (reader.peek() == JsonToken.NULL) {
                reader.nextNull();
                return "";
            }
            return reader.nextString();
        }
        @Override
        public void write(JsonWriter writer, String value) throws IOException {
            if (value == null) {
                writer.nullValue();
                return;
            }
            writer.value(value);
        }
    }
    static class NullStringToEmptyAdapterFactory<T> implements TypeAdapterFactory {
        public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
            Class<T> rawType = (Class<T>) type.getRawType();
            if (rawType != String.class) {
                return null;
            }
            return (TypeAdapter<T>) new StringNullAdapter();
        }
    }


    private static final Gson gson = new GsonBuilder()
            .registerTypeAdapter(Integer.class, integerTypeAdapter) //null的Integer类型返回0
            .registerTypeAdapter(Long.class, longTypeAdapter) //null的Long类型返回0
            .registerTypeAdapter(Float.class, floatTypeAdapter) //null的Float类型返回0
            .registerTypeAdapter(Double.class, doubleTypeAdapter) //null的Double类型返回0
            .registerTypeAdapter(Boolean.class, booleanTypeAdapter) //null的Boolean类型返回false
            .registerTypeAdapter(BigInteger.class, bigIntegerTypeAdapter) //null的BigInteger类型返回0
            .registerTypeAdapter(BigDecimal.class, decimalTypeAdapter) //null的BigDecimal类型返回0
            .registerTypeAdapter(Date.class, dateTypeAdapter) //null的date类型返回null
            .registerTypeAdapterFactory(new NullStringToEmptyAdapterFactory<String>()) //null的string类型返回""
            .setLenient()
            .serializeNulls()
            //.setDateFormat(DATE_TIME_PATTERN_DEFAULT)
            .create();

    public static String toJsonStr(Object obj) {
        return gson.toJson(obj);
    }

    public static <T> T fromJson(String json, Class<T> classOfT) {
        return gson.fromJson(json, classOfT);
    }
}

3、常用注解

@SerializedName("user_name")  //能指定该字段在JSON中对应的字段名称
@SerializedName(value = "name", alternate = {"name1","name2"})

@Expose //指定该字段是否能够序列化或者反序列化,默认的是都支持(true)
@Expose(serialize = false, deserialize = false)

@Since(1.0)代表从版本1.0之后才生效
@Until(0.9)代表着在0.9版本之前都是生效的

--------------------------------------------------------

创建测试数据model

{
  "id": 1,
  "user_name": "zhangsan",
  "password": "123456qwe",
  "age": 12,
  "student": true,
  "balance1": 1.123,
  "balance2": 1.123,
  "balance": 1.456,
  "createTime": "2020-04-07T06:20:52.497+0000",
  "descr": "说明内容……",
  "sub": {
    "id": null,
    "user_name": "zhangsan",
    "password": "",
    "age": null,
    "student": null,
    "balance1": null,
    "balance2": null,
    "balance": null,
    "createTime": null,
    "descr": null
  },
  "subList": [
    {
      "id": 2,
      "user_name": "zhangsan",
      "password": "123456qwe",
      "age": 12,
      "student": true,
      "balance1": 1.123,
      "balance2": 1.123,
      "balance": 1.123,
      "createTime": "2020-04-07T06:20:52.497+0000",
      "descr": "说明内容……"
    },
    {
      "id": 3,
      "user_name": "zhangsan",
      "password": "123456qwe",
      "age": 12,
      "student": false,
      "balance1": 1.123,
      "balance2": 1.123,
      "balance": 1.456,
      "createTime": "2020-04-07T06:20:52.497+0000",
      "descr": ""
    }
  ]
}

测试结果

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!