1、序列化之Java序列化工具详解

本文详细介绍了Java中常用的序列化和反序列化工具,包括Jackson、Gson和Fastjson。Jackson以其高性能和低内存占用成为SpringMVC的默认选择,Gson则因其对Java特性的良好支持受到青睐,而Fastjson则以其速度著称。对于小数据量,推荐使用Gson,大数据量场景下Jackson更优,但Fastjson在某些情况下可能存在安全问题。
摘要由CSDN通过智能技术生成

Java的序列化与反序列化工具详解

1、序列化和反序列化定义

序列化:Java序列化是指把Java对象转换为可传输的字节序列的过程;

反序列化:而Java反序列化是指把传输的字节序列恢复为Java对象的过程。这两个过程使我们非常方便的存储和传输数据。

2、工具介绍

2.1、Jackson(即ObjectMapper)

2.1.1概述:
	Jackson 是当前用的比较广泛的,用来序列化和反序列化 json 的 Java 的开源框架。Jackson 社区相对比较活跃,更新速度也比较快, 从 Github 中的统计来看,Jackson 是最流行的 json 解析器之一 。 
2.1.2、优点:
	Spring MVC 的默认 json 解析器便是 Jackson。 
	Jackson 所依赖的 jar 包较少 ,简单易用。
	与其他 Java 的 json 的框架 Gson 等相比, Jackson 解析大的 json 文件速度比较快;
	Jackson 运行时占用内存比较低,性能比较好;
	Jackson 有灵活的 API,可以很容易进行扩展和定制。
2.1.3、使用方法:
jackson
//maven依赖
//该依赖同时会将如下库添加到项目路径中:
//jackson-annotations-2.9.8.jar
//jackson-core-2.9.8.jar
//jackson-databind-2.9.8.jar
<!-- json数据的解析包 -->
  <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.9.3</version>
  </dependency>
   
//导包: 
import com.fasterxml.jackson.databind.ObjectMapper;

//序列化
ObjectMapper mapper = new ObjectMapper();
String s = mapper.writeValueAsString(all);
//反序列化
ObjectMapper mapper = new ObjectMapper();
List list = mapper.readValue(categories, List.class);
2.1.4、工具类:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * @author :
 * @date :Created in 19:30 2022/7/18
 * @description :
 * @version: 1.0
 */
public class ObjectMapperUtils {

    public static final ObjectMapper mapper = new ObjectMapper();

    private static final Logger logger = LoggerFactory.getLogger(JsonUtils.class);

    public static String toString(Object obj) {
        if (obj == null) {
            return null;
        }
        if (obj.getClass() == String.class) {
            return (String) obj;
        }
        try {
            return mapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            logger.error("json序列化出错:" + obj, e);
            return null;
        }
    }

    public static <T> T toBean(String json, Class<T> tClass) {
        try {
            return mapper.readValue(json, tClass);
        } catch (IOException e) {
            logger.error("json解析出错:" + json, e);
            return null;
        }
    }

    public static <E> List<E> toList(String json, Class<E> eClass) {
        try {
            return mapper.readValue(json, mapper.getTypeFactory().constructCollectionType(List.class, eClass));
        } catch (IOException e) {
            logger.error("json解析出错:" + json, e);
            return null;
        }
    }

    public static <K, V> Map<K, V> toMap(String json, Class<K> kClass, Class<V> vClass) {
        try {
            return mapper.readValue(json, mapper.getTypeFactory().constructMapType(Map.class, kClass, vClass));
        } catch (IOException e) {
            logger.error("json解析出错:" + json, e);
            return null;
        }
    }

    public static <T> T nativeRead(String json, TypeReference<T> type) {
        try {
            return mapper.readValue(json, type);
        } catch (IOException e) {
            logger.error("json解析出错:" + json, e);
            return null;
        }
    }
}

2.2、Gson

2.2.1、概述:
	Gson是一个Java库,可用于将Java对象转换为JSON表示,它也可以用来将JSON字符串转换为等效的Java对象。使用的主要类是Gson,可以通过调用创建new Gson(),Gson实例在调用Json操作时不保持任何状态,所以,你可以自由地重复使用同一个对象来进行多个Json序列化和反序列化操作。
2.2.2、优点:
1.gson默认支持LocalData;
2.如果字段被标记为transient,(默认情况下)它会被忽略并且不包含在 JSON 序列化或反序列化中;
3.此实现正确处理空值,序列化时,从输出中跳过空字段反序列化时,JSON 中缺少条目导致将对象中的相应字段设置为 null;
4.如果字段是synthetic的,则它会被忽略并且不包括在 JSON 序列化或反序列化中。
2.2.3、使用方法:
//maven依赖
<dependency>
  <groupId>com.google.code.gson</groupId>
  <artifactId>gson</artifactId>
  <version>2.8.6</version>
</dependency>
       
//需要导包
import com.google.gson.Gson;

//序列化
String s = new Gson().toJson(setMealDetails);
//反序列化
Setmeal setmeal = new Gson().fromJson(json, Setmeal.class);
2.2.4、工具类:

import cn.hutool.core.date.DatePattern;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.reflect.TypeToken;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author :
 * @date :Created in 20:12 2022/7/18
 * @description :Gson序列化工具类
 * @version: 1.0
 */
@Slf4j
public class GsonSerializeUtils {

    public static final Gson gsonToJson = new GsonBuilder()
            .registerTypeAdapter(LocalDateTime.class, new JsonSerializer<LocalDateTime>() {
                @Override
                public JsonElement serialize(LocalDateTime localDateTime, Type type, JsonSerializationContext jsonSerializationContext) {
                    return new JsonPrimitive(localDateTime.format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)));
                }
            })
            .registerTypeAdapter(LocalDate.class, new JsonSerializer<LocalDate>() {
                @Override
                public JsonElement serialize(LocalDate localDate, Type typeOfSrc, JsonSerializationContext context) {
                    return new JsonPrimitive(localDate.format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN)));
                }
            })
            .registerTypeAdapter(Date.class, new JsonSerializer<Date>() {
                @Override
                public JsonElement serialize(Date date, Type typeOfSrc, JsonSerializationContext context) {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DatePattern.NORM_DATETIME_PATTERN);
                    String dateString = simpleDateFormat.format(date);
                    return new JsonPrimitive(dateString);
                }
            })
            .serializeNulls()
            .create();


    public static final  Gson gsonToBean = new GsonBuilder()
            .registerTypeAdapter(LocalDateTime.class, new JsonDeserializer() {
                @Override
                public LocalDateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
                    return LocalDateTime.parse(json.getAsJsonPrimitive().getAsString(), DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN));
                }
            })
            .registerTypeAdapter(LocalDate.class, new JsonDeserializer() {
                @Override
                public LocalDate deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
                    return LocalDate.parse(json.getAsJsonPrimitive().getAsString(), DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN));
                }
            })
            .registerTypeAdapter(Date.class, new JsonDeserializer() {
                @SneakyThrows
                @Override
                public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DatePattern.NORM_DATETIME_PATTERN);
                    return simpleDateFormat.parse(json.getAsJsonPrimitive().getAsString());
                }
            })
            .create();

    public static String toString(Object obj) {
        if (obj.getClass() == String.class) {
            return (String) obj;
        }
        try {
            return gsonToJson.toJson(obj);
        } catch (Exception e) {
            log.error("json序列化出错:" + obj, e);
            return null;
        }
    }

    public static <T> T toBean(String json, Class<T> tClass) {
        if(json == null || json.equals("")){
            return null;
        }
        try {
            return gsonToBean.fromJson(json, tClass);
        } catch (Exception e) {
            log.error("json解析Bean出错:" + json, e);
            return null;
        }
    }

    public static <E> List<E> toList(String json, Class<E> eClass) {
        try {
            return gsonToBean.fromJson(json, new TypeToken<List<E>>(){}.getType());
        } catch (Exception e) {
            log.error("json解析List出错:" + json, e);
            return null;
        }
    }

    public static <K, V> Map<K, V> toMap(String json, Class<K> kClass, Class<V> vClass) {
        try {
            return gsonToBean.fromJson(json, new TypeToken<Map<K, V>>(){}.getType());
        } catch (Exception e) {
            log.error("json解析出错:" + json, e);
            return null;
        }
    }

    public static <T> T nativeRead(String json,  TypeToken typeToken) {
        try {
            return gsonToBean.fromJson(json, typeToken.getType());
        } catch (Exception e) {
            log.error("json解析出错:" + json, e);
            return null;
        }
    }

}

2.3、Fastjson

2.3.1、概述:
	JSON、JSONObject都是FastJson框架中的东西,JSON协议使用方便,越来越流行,JSON的处理器有很多,这里先介绍一下FastJson,FastJson是阿里的开源框架,被不少企业使用,是一个极其优秀的Json框架。
2.3.2、优点:

​ 1.FastJson数度快,无论序列化和反序列化,都是当之无愧的fast

​ 2.功能强大(支持普通JDK类包括任意Java Bean Class、Collection、Map、Date或enum)

​ 3.零依赖(没有依赖其它任何类库)

2.3.3、JSON、JSONObject、javabean关系的解析:

​ 首先JSON、JSONObject是属于FastJson框架的类,它们就是普通的类只不过在FastJson框架赋予了它们对json格式字符的处理能力。

JSON:fastJson的解析器,用于JSON格式字符串与JSON对象及javaBean之间的转换。

JSONObject:fastJson提供处理对象样子的json字符的类。

2.3.4、使用方法:
//maven依赖
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>fastjson</artifactId>
  <version>1.2.58</version>
</dependency>

//导包
import com.alibaba.fastjson.JSONObject;


//序列化
String jsonString = JSON.toJSONString(updateResponse)
//反序列化
Student student = JSON.parseObject("对象样子的json字符", new TypeReference<Student>() {});

//反序列化 json格式数据(需要是最外层为{}包裹的)转换为Map集合
//如果最外层是[]包裹的,则需要使用parseArray()方法来处理转换为List集合
Map<String, String> spec = JSON.parseObject(sku.getSpec(), Map.class);

//将json格式字符串转换成List集合, 如果json字符串最外层是方括号[]使用这个方法
//JSON.parseArray();

2.4、性能对比及选择

当数据量较小的时候(1~100),建议使用 Gson;
当数据量较大的时候,建议使用Jackson;
在大数据量的时候,虽然FastJson优势上来了,但是因为有漏洞,不得不放弃。
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白de成长之路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值