The efficiency of common serialization and deserialization methods:
protoBuf(PB) > fastjson > jackson > hessian > xstream > java
Data comes from: https://github.com/eishay/jvm-serializers/wiki
So I chose java method, jackson method, fastjson method, pb method to encapsulate and test, the test results are as follows:
Jackson, pb, and fastjson are not too different. Jackson is slightly better. The java method is very slow. It is not recommended. Jackson is the json serialization tool that comes with springboot, so this method is recommended for redis object access.
The following are four ways to achieve:
Java comes with serialization
Serialization tool method
/** * Serialization * * @param object * @return */ public static byte[] serialize(Object object) { ObjectOutputStream east = null; ByteArrayOutputStream baos = null; try { // Serialization baos = new ByteArrayOutputStream(); oos = new ObjectOutputStream (baos); oos.writeObject(object); byte[] bytes = baos.toByteArray(); return bytes; } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } } /** * Deserialization * * @param bytes * @return */ public static Object unserialize(byte[] bytes) { ByteArrayInputStream bais = null; try { // Deserialization bais = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(bais); return ois.readObject(); } catch (Exception e) { throw new RuntimeException(e.getMessage(), e); } }
redisUtils
@Autowired
private StringRedisTemplate redisTemplate;
/** * Save objects to redis in binary serialization mode 2019 * * @param key * @param value */ public void setObj(String key, Object value) { final byte[] vbytes = SerializeUtil.serialize(value); redisTemplate.execute(new RedisCallback() { @Override public Object doInRedis(RedisConnection connection) throws DataAccessException { // connection.set(redisTemplateSer.getStringSerializer().serialize(key), vbytes); connection.set(SerializeUtil.serialize(key), vbytes); return null; } }); } /** * Obtain objects from redis in binary serialization mode 2019 * * @param key * @param <T> * @return */ public <T> T getObj(String key) { return redisTemplate.execute(new RedisCallback<T>() { @Override public T doInRedis(RedisConnection connection) throws DataAccessException { // byte[] keyByte = redisTemplateSer.getStringSerializer().serialize(key); byte[] keyByte = SerializeUtil.serialize(key); if (connection.exists(keyByte)) { byte[] valuebytes = connection.get(keyByte); @SuppressWarnings("unchecked") T value = (T) SerializeUtil.unserialize(valuebytes); return value; } return null; } }); }
Jackson 、 fastjson
Serialization tool method
/** * Jackson serialization and deserialization tools */ private static ObjectMapper objectMapper = new ObjectMapper(); public static <T> String obj2String(T obj) { if (obj == null) { return null; } try { return obj instanceof String ? (String) obj : objectMapper.writeValueAsString(obj); } catch (Exception e) { e.printStackTrace (); return null; } } //String to object public static <T> T string2Obj(String str, Class<T> clazz) { if (StringUtils.isEmpty(str) || clazz == null) { return null; } try { return clazz.equals(String.class) ? (T) str : objectMapper.readValue(str, clazz); } catch (IOException e) { e.printStackTrace (); return null; } } // /** // * fastjson serialization and deserialization tool // */ // public static <T> String obj2String(T obj) { // return JSON.toJSONString(obj); // } // // //String to object // public static <T> T string2Obj(String str, Class<T> clazz) { // return JSON.parseObject(str,clazz); // }
redisUtils
/** * It is recommended to save objects to redis in the way of JSON serialization. This usage is fast.2019 * @param key * @param value */ public void setObjJson(String key,Object value){ redisTemplate.opsForValue().set(key,SerializeUtil.obj2String(value)); } /** * It is recommended to obtain objects from redis in JSON serialization, which is fast in usage.2019 * @param key * @param clazz * @param <T> * @return */ public <T> T getObjJson(String key,Class<T> clazz){ String strValue = redisTemplate.opsForValue().get(key); if(!StringUtils.isEmpty(strValue)){ T value = SerializeUtil.string2Obj(strValue,clazz); return value; } return null; }
ProtoBuf method
maven dependency
<!-- protostuff --> <dependency> <groupId>io.protostuff</groupId> <artifactId>protostuff-core</artifactId> <version>1.4.0</version> </dependency> <dependency> <groupId>io.protostuff</groupId> <artifactId>protostuff-runtime</artifactId> <version>1.4.0</version> </dependency>
Serialization tool method
/** * protobuf serialization tool */ public static <T> byte[] serializePb(T o) { Schema schema = RuntimeSchema.getSchema(o.getClass()); return ProtobufIOUtil.toByteArray(o, schema, LinkedBuffer.allocate(256)); } public static <T> T unserializePb(byte[] bytes, Class<T> clazz) { T obj = null; try { obj = clazz.newInstance(); Schema schema = RuntimeSchema.getSchema(obj.getClass()); ProtostuffIOUtil.mergeFrom(bytes, obj, schema); } catch (InstantiationException e) { e.printStackTrace (); } catch (IllegalAccessException e) { e.printStackTrace (); } return obj; }
If the redisUtils, pb method is a nested object, there will be some problems (we will look at it later), and the member variables that need to be serialized need to be annotated with @Tag(7), such as:
@Data public class SimplePojo { @Tag(1) private String a; @Tag(2) private String b; @Tag(3) private String c;
/** * Save objects to redis in pb serialization mode 2019 * * @param key * @param value */ public void setObjPb(String key, Object value) { final byte[] vbytes = SerializeUtil.serializePb(value); redisTemplate.execute(new RedisCallback() { @Override public Object doInRedis(RedisConnection connection) throws DataAccessException { connection.set(SerializeUtil.serializePb(key), vbytes); return null; } }); } /** * Obtain objects from redis in pb serialization mode 2019 * * @param key * @param <T> * @return */ public <T> T getObjPb(String key,Class<T> clazz) { return redisTemplate.execute(new RedisCallback<T>() { @Override public T doInRedis(RedisConnection connection) throws DataAccessException { byte[] keyByte = SerializeUtil.serializePb(key); if (connection.exists(keyByte)) { byte[] valuebytes = connection.get(keyByte); @SuppressWarnings("unchecked") T value = (T) SerializeUtil.unserializePb(valuebytes,clazz); return value; } return null; } }); }