Kryo序列化及反序列化對象

    Kryo 是一個快速高效的Java對象圖形序列化框架,主要特點是性能、高效和易用。該項目用來序列化對象到文件、數據庫或者網絡。

    代碼地址:https://github.com/EsotericSoftware/kryo

    樣例代碼地址:https://github.com/nettm/public

    Kryo的序列化及反序列速度很快,據說很多大公司都在用。我在把對象序列化都轉換成了字符串形式,是爲了把對象存儲到緩存中。我們日常項目中使用的數據形式包括對象、List、Set和Map,因此主要把這幾種類型的數據進行了序列化及反序列化,支持對象中包含List、Set和Map。

首先在項目的pom文件中引入:

<dependency>
	<groupId>com.esotericsoftware</groupId>
	<artifactId>kryo-shaded</artifactId>
	<version>3.0.3</version>
</dependency>

代碼KryoTest:

package com.nettm.serializable;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.codec.binary.Base64;
import org.testng.Assert;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.kryo.serializers.CollectionSerializer;
import com.esotericsoftware.kryo.serializers.JavaSerializer;
import com.esotericsoftware.kryo.serializers.MapSerializer;

public class KryoTest {

    private long time;

    @BeforeTest
    public void beforeTest() {
        time = System.currentTimeMillis();
    }

    @AfterTest
    public void afterTest() {
        System.out.println(System.currentTimeMillis() - time);
    }

    @Test(invocationCount = 1, threadPoolSize = 1)
    public void testObject() {
        CustomItemDto val = new CustomItemDto();
        val.setId(Long.parseLong(String.valueOf(1)));
        val.setItemCode("");
        val.setItemDespositPrice(32.45);
        val.setItemMemo(null);
        val.setItemName("張金");
        val.setItemPrice(89.02);
        val.setSort(10);

        String a = serializationObject(val);
        CustomItemDto newValue = deserializationObject(a, CustomItemDto.class);
        Assert.assertEquals(val.getId(), newValue.getId());
    }

    @Test(invocationCount = 1, threadPoolSize = 1)
    public void testList() {
        List<CustomItemDto> lst = new ArrayList<CustomItemDto>();
        for (int i = 0; i < 10; i++) {
            CustomItemDto val = new CustomItemDto();
            val.setId(Long.parseLong(String.valueOf(i)));
            val.setItemCode("");
            val.setItemDespositPrice(32.45);
            val.setItemMemo(null);
            val.setItemName("張金");
            val.setItemPrice(89.02);
            val.setSort(10);
            lst.add(val);
        }

        String a = serializationList(lst, CustomItemDto.class);
        List<CustomItemDto> newValue = deserializationList(a,
                CustomItemDto.class);
        Assert.assertEquals(lst.size(), newValue.size());
    }

    @Test(invocationCount = 1, threadPoolSize = 1)
    public void testBean() {
        List<CustomCategoryDto> lst = new ArrayList<CustomCategoryDto>();
        for (int j = 0; j < 10; j++) {
            CustomCategoryDto dto = new CustomCategoryDto();
            dto.setCategoryCode("ABCD_001");
            dto.setCategoryName("呼吸系統");
            for (int i = 0; i < 10; i++) {
                CustomItemDto val = new CustomItemDto();
                val.setId(Long.parseLong(String.valueOf(i)));
                val.setItemCode("");
                val.setItemDespositPrice(32.45);
                val.setItemMemo(null);
                val.setItemName("張金");
                val.setItemPrice(89.02);
                val.setSort(10);
                dto.getCustomItemList().add(val);
            }
            for (int i = 0; i < 10; i++) {
                CustomItemDto val = new CustomItemDto();
                val.setId(Long.parseLong(String.valueOf(i)));
                val.setItemCode("");
                val.setItemDespositPrice(32.45);
                val.setItemMemo(null);
                val.setItemName("張金");
                val.setItemPrice(89.02);
                val.setSort(10);
                dto.getCustomItemSet().add(val);
            }
            for (int i = 0; i < 10; i++) {
                CustomItemDto val = new CustomItemDto();
                val.setId(Long.parseLong(String.valueOf(i)));
                val.setItemCode("");
                val.setItemDespositPrice(32.45);
                val.setItemMemo(null);
                val.setItemName("張金");
                val.setItemPrice(89.02);
                val.setSort(10);
                dto.getCustomItemMap().put(String.valueOf(i), val);
            }
            lst.add(dto);
        }

        String a = serializationList(lst, CustomCategoryDto.class);
        List<CustomCategoryDto> newValue = deserializationList(a,
                CustomCategoryDto.class);
        Assert.assertEquals(lst.size(), newValue.size());
    }

    @Test(invocationCount = 1, threadPoolSize = 1)
    public void testMap() {
        Map<String, CustomItemDto> map = new HashMap<String, CustomItemDto>();
        for (int i = 0; i < 10; i++) {
            CustomItemDto val = new CustomItemDto();
            val.setId(Long.parseLong(String.valueOf(i)));
            val.setItemCode("");
            val.setItemDespositPrice(32.45);
            val.setItemMemo(null);
            val.setItemName("張金");
            val.setItemPrice(89.02);
            val.setSort(10);
            map.put(new ObjectId().toString(), val);
        }

        String a = serializationMap(map, CustomItemDto.class);
        Map<String, CustomItemDto> newValue = deserializationMap(a,
                CustomItemDto.class);
        Assert.assertEquals(map.size(), newValue.size());
    }

    @Test(invocationCount = 1, threadPoolSize = 1)
    public void testSet() {
        Set<CustomItemDto> set = new HashSet<CustomItemDto>();
        for (int i = 0; i < 10; i++) {
            CustomItemDto val = new CustomItemDto();
            val.setId(Long.parseLong(String.valueOf(i)));
            val.setItemCode("");
            val.setItemDespositPrice(32.45);
            val.setItemMemo(null);
            val.setItemName("金星");
            val.setItemPrice(89.02);
            val.setSort(10);
            set.add(val);
        }

        String a = serializationSet(set, CustomItemDto.class);
        Set<CustomItemDto> newValue = deserializationSet(a, CustomItemDto.class);
        Assert.assertEquals(set.size(), newValue.size());
    }

    private <T extends Serializable> String serializationObject(T obj) {
        Kryo kryo = new Kryo();
        kryo.setReferences(false);
        kryo.register(obj.getClass(), new JavaSerializer());

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Output output = new Output(baos);
        kryo.writeClassAndObject(output, obj);
        output.flush();
        output.close();

        byte[] b = baos.toByteArray();
        try {
            baos.flush();
            baos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return new String(new Base64().encode(b));
    }

    @SuppressWarnings("unchecked")
    private <T extends Serializable> T deserializationObject(String obj,
            Class<T> clazz) {
        Kryo kryo = new Kryo();
        kryo.setReferences(false);
        kryo.register(clazz, new JavaSerializer());

        ByteArrayInputStream bais = new ByteArrayInputStream(
                new Base64().decode(obj));
        Input input = new Input(bais);
        return (T) kryo.readClassAndObject(input);
    }

    private <T extends Serializable> String serializationList(List<T> obj,
            Class<T> clazz) {
        Kryo kryo = new Kryo();
        kryo.setReferences(false);
        kryo.setRegistrationRequired(true);

        CollectionSerializer serializer = new CollectionSerializer();
        serializer.setElementClass(clazz, new JavaSerializer());
        serializer.setElementsCanBeNull(false);

        kryo.register(clazz, new JavaSerializer());
        kryo.register(ArrayList.class, serializer);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Output output = new Output(baos);
        kryo.writeObject(output, obj);
        output.flush();
        output.close();

        byte[] b = baos.toByteArray();
        try {
            baos.flush();
            baos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return new String(new Base64().encode(b));
    }

    @SuppressWarnings("unchecked")
    private <T extends Serializable> List<T> deserializationList(String obj,
            Class<T> clazz) {
        Kryo kryo = new Kryo();
        kryo.setReferences(false);
        kryo.setRegistrationRequired(true);

        CollectionSerializer serializer = new CollectionSerializer();
        serializer.setElementClass(clazz, new JavaSerializer());
        serializer.setElementsCanBeNull(false);

        kryo.register(clazz, new JavaSerializer());
        kryo.register(ArrayList.class, serializer);

        ByteArrayInputStream bais = new ByteArrayInputStream(
                new Base64().decode(obj));
        Input input = new Input(bais);
        return (List<T>) kryo.readObject(input, ArrayList.class, serializer);
    }

    private <T extends Serializable> String serializationMap(
            Map<String, T> obj, Class<T> clazz) {
        Kryo kryo = new Kryo();
        kryo.setReferences(false);
        kryo.setRegistrationRequired(true);

        MapSerializer serializer = new MapSerializer();
        serializer.setKeyClass(String.class, new JavaSerializer());
        serializer.setKeysCanBeNull(false);
        serializer.setValueClass(clazz, new JavaSerializer());
        serializer.setValuesCanBeNull(true);

        kryo.register(clazz, new JavaSerializer());
        kryo.register(HashMap.class, serializer);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Output output = new Output(baos);
        kryo.writeObject(output, obj);
        output.flush();
        output.close();

        byte[] b = baos.toByteArray();
        try {
            baos.flush();
            baos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return new String(new Base64().encode(b));
    }

    @SuppressWarnings("unchecked")
    private <T extends Serializable> Map<String, T> deserializationMap(
            String obj, Class<T> clazz) {
        Kryo kryo = new Kryo();
        kryo.setReferences(false);
        kryo.setRegistrationRequired(true);

        MapSerializer serializer = new MapSerializer();
        serializer.setKeyClass(String.class, new JavaSerializer());
        serializer.setKeysCanBeNull(false);
        serializer.setValueClass(clazz, new JavaSerializer());
        serializer.setValuesCanBeNull(true);

        kryo.register(clazz, new JavaSerializer());
        kryo.register(HashMap.class, serializer);

        ByteArrayInputStream bais = new ByteArrayInputStream(
                new Base64().decode(obj));
        Input input = new Input(bais);
        return (Map<String, T>) kryo.readObject(input, HashMap.class,
                serializer);
    }

    public static <T extends Serializable> String serializationSet(Set<T> obj,
            Class<T> clazz) {
        Kryo kryo = new Kryo();
        kryo.setReferences(false);
        kryo.setRegistrationRequired(true);

        CollectionSerializer serializer = new CollectionSerializer();
        serializer.setElementClass(clazz, new JavaSerializer());
        serializer.setElementsCanBeNull(false);

        kryo.register(clazz, new JavaSerializer());
        kryo.register(HashSet.class, serializer);

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        Output output = new Output(baos);
        kryo.writeObject(output, obj);
        output.flush();
        output.close();

        byte[] b = baos.toByteArray();
        try {
            baos.flush();
            baos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return new String(new Base64().encode(b));
    }

    @SuppressWarnings("unchecked")
    public static <T extends Serializable> Set<T> deserializationSet(
            String obj, Class<T> clazz) {
        Kryo kryo = new Kryo();
        kryo.setReferences(false);
        kryo.setRegistrationRequired(true);

        CollectionSerializer serializer = new CollectionSerializer();
        serializer.setElementClass(clazz, new JavaSerializer());
        serializer.setElementsCanBeNull(false);

        kryo.register(clazz, new JavaSerializer());
        kryo.register(HashSet.class, serializer);

        ByteArrayInputStream bais = new ByteArrayInputStream(
                new Base64().decode(obj));
        Input input = new Input(bais);
        return (Set<T>) kryo.readObject(input, HashSet.class, serializer);
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章