Json工具类之Gson

242 阅读1分钟

介绍

Gson 是一个 Java 库,可用于将 Java 对象转换为其 JSON 表示形式。 它还可用于将 JSON 字符串转换为等效的 Java 对象。 Gson 可以使用任意 Java 对象,包括您没有源代码的预先存在的对象。

引入maven依赖

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

实现

public class GsonUtils {

    public static final Gson IDENTITY_GSON;
    public static final Gson LOWER_CASE_GSON;
    public static final GsonBuilderCustomizer LOWER_CASE_GSON_BUILDER_CUSTOMIZER = builder -> builder
            .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
            .registerTypeAdapter(Date.class, new JsonSerializerOfDateImpl())
            .registerTypeAdapter(Date.class, new JsonDeserializerOfDateImpl())
            .registerTypeAdapter(LocalDateTime.class, new JsonSerializerOfLocalDateTimeImpl())
            .registerTypeAdapter(LocalDateTime.class, new JsonDeserializerOfLocalDateTimeImpl())
            .addSerializationExclusionStrategy((ExposedFieldExclusionStrategy) (clazz) -> false)
            .addDeserializationExclusionStrategy((ExposedFieldExclusionStrategy) (clazz) -> false);

    static {
        GsonBuilder gsonBuilder = new GsonBuilder();
        LOWER_CASE_GSON_BUILDER_CUSTOMIZER.customize(gsonBuilder);
        LOWER_CASE_GSON = gsonBuilder.create();
        IDENTITY_GSON = LOWER_CASE_GSON.newBuilder().setFieldNamingPolicy(FieldNamingPolicy.IDENTITY).create();
    }

    public static <T> String toJson(T object) {
        return LOWER_CASE_GSON.toJson(object);
    }

    public static <T> T fromJson(String json, Class<T> clazz) {
        return fromJson(json, clazz, true);
    }

    public static <T> T fromJson(String json, Type type) {
        return LOWER_CASE_GSON.fromJson(json, type);
    }

    public static <T> T fromJson(String json, TypeToken<T> typeToken) {
        return LOWER_CASE_GSON.fromJson(json, typeToken.getType());
    }

    private static <T> T fromJson(String json, Class<T> clazz, boolean lowerCaseWithUnderscores) {
        if (!lowerCaseWithUnderscores) {
            return IDENTITY_GSON.fromJson(json, clazz);
        }
        return LOWER_CASE_GSON.fromJson(json, clazz);
    }

    @SuppressWarnings("unchecked")
    public static Map<String, Object> beanToLowerCaseMap(Object bean) {
        Map<String, Object> result = new HashMap<>();
        BeanMap map = BeanMap.create(bean);
        map.forEach((key, value) -> {
            if (Objects.nonNull(value)) {
                String lowKey = separateCamelCase(key.toString(), "_");
                result.put(lowKey, value);
            }
        });
        return result;
    }

    public static String separateCamelCase(String name, String separator) {
        StringBuilder translation = new StringBuilder();
        for (int i = 0, length = name.length(); i < length; i++) {
            char character = name.charAt(i);
            if (Character.isUpperCase(character) && translation.length() != 0) {
                translation.append(separator);
            }
            translation.append(character);
        }
        return translation.toString().toLowerCase(Locale.ENGLISH);
    }

    public static class JsonSerializerOfDateImpl implements JsonSerializer<Date> {
        @Override
        public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) {
            return new JsonPrimitive(Instant.ofEpochSecond(src.getTime()).atZone(ZoneOffset.UTC).toInstant().toEpochMilli() / 1000_000);
        }
    }

    public static class JsonDeserializerOfDateImpl implements JsonDeserializer<Date> {
        @Override
        public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            return json.getAsLong() == 0 ? null : (new Date(Instant.ofEpochSecond(json.getAsLong()).atZone(ZoneOffset.UTC).toInstant().toEpochMilli()));
        }
    }

    public static class JsonSerializerOfLocalDateTimeImpl implements JsonSerializer<LocalDateTime> {

        @Override
        public JsonElement serialize(LocalDateTime src, Type typeOfSrc, JsonSerializationContext context) {
            return new JsonPrimitive(src.toEpochSecond(ZoneOffset.ofHours(8)));
        }
    }
    
    public static class JsonDeserializerOfLocalDateTimeImpl implements JsonDeserializer<LocalDateTime> {

        @Override
        public LocalDateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            return json.getAsLong() == 0 ? null :  LocalDateTime.ofEpochSecond(json.getAsLong(), 0, ZoneOffset.ofHours(8));
        }
    }

    @FunctionalInterface
    public interface ExposedFieldExclusionStrategy extends ExclusionStrategy {
        @Override
        default boolean shouldSkipField(FieldAttributes fieldAttributes) {
            final Expose expose = fieldAttributes.getAnnotation(Expose.class);
            return expose != null && !expose.deserialize();
        }
    }
}