java对象序列化为字符串
文章目录
- 1 场景
- 2 应用
- 2.1 过程描述
- 2.2 字节数组、字符串转换
- 2.2.1 hex转码
- 2.2.2 base64转码
- 2.3 对象序列化字节数组
- 2.3.1 使用commons-lang3包实现对象序列化
- 2.3.2 编码实现对象序列化
- 2.4 完整工具类代码
- 2.4.1 maven依赖
- 2.4.2 java代码
- 3 限制
- 3.1 序列化前置条件
- 3.2 字节数组转换字符串
- 3.3 序列化时忽略属性
- 4 扩展
- 4.1 hex和base64
- 4.2 base32
1 场景
java对象
某些时候,需要序列化
成字符串
存储在数据库中,需要的时候,再将字符串反序列化
为java对象。
如使用shiro缓存分布式session
,需要将session对象序列化成字符串存储在redis中,来达到分布式应用共享session的功能。
为什么不序列化成json?
java对象同样可以转换为`json`,需要的时候,再转换为java对象。这种情况一般只适用转换`自己创建的javaBean对象`,如果类是非自己管理的javaBean,对象内部`存在没有对外开放set/get方法的属性`,转换后将`丢失`。序列化自己javaBean对象的好处是,通过序列化后的json字符串,可以很清楚知道`被序列化的java对象的内容`。
2 应用
2.1 过程描述
序列化过程:
(1)java对象通过对象输出流ObjectOutputStream
,写入到内存字节数组输出流ByteArrayOutputStream
中
(2)通过内存字节数组输出流ByteArrayOutputStream
获取字节数组byte[]
(3)字节数组根据自定义算法
转换成字符串(hex/base64等)
反序列化过程:
(1)被序列化后字符串
,根据字节数组转换字符串的算法
,转换为字节数组byte[]
(2)字节数组通过内存字节数组输入流ByteArrayInputStream
写入到对象输入流ObjectInputStream
(3)通过对象输入流ObjectInputStream读取java对象
2.2 字节数组、字符串转换
字节数组转码成字符串依赖如下maven包:
<dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>1.14</version>
</dependency>
2.2.1 hex转码
(1)字节数组hex转码
public static String bytesToString(byte[] bytes) {//转换成hexreturn org.apache.commons.codec.binary.Hex.encodeHexString(bytes);
}
(2)字符串hex反转码成字节数组
public static byte[] stringToByte(String str) throws DecoderException {//转换成hexreturn org.apache.commons.codec.binary.Hex.decodeHex(str);
}
2.2.2 base64转码
建议此种方式
(1) 字节数组base64转码
public static String bytesToString(byte[] bytes) {//转换成base64return org.apache.commons.codec.binary.Base64.encodeBase64String(bytes);
}
(2) 字符串base64反转码成字节数组
public static byte[] stringToByte(String str) throws DecoderException {//转换成base64return org.apache.commons.codec.binary.Base64.decodeBase64(str);
}
2.3 对象序列化字节数组
字节数组、字符串转换使用2.2
中定义的转换方法:bytesToString、stringToByte
2.3.1 使用commons-lang3包实现对象序列化
建议此种方式,代码简单
maven依赖如下:
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.10</version>
</dependency>
代码如下:
(1)java对象序列化成字符串
public static String serialize(Serializable obj) throws Exception{if(obj!=null) {byte[] bytes = SerializationUtils.serialize(obj);return bytesToString(bytes);}return null;
}
(2)字符串反序列化成java对象
public static <T extends Serializable> T deserialize(String str) throws Exception{if(StringUtils.isNotEmpty(str)){return SerializationUtils.deserialize(stringToByte(str));}return null;
}
2.3.2 编码实现对象序列化
代码如下:
(1)java对象序列化成字符串
public static String serialize(Serializable obj) throws Exception{if(obj!=null) {ByteArrayOutputStream bos=null;ObjectOutputStream oos=null;try {bos=new ByteArrayOutputStream();oos=new ObjectOutputStream(bos);oos.writeObject(obj);byte[] bytes = bos.toByteArray();return bytesToString(bytes);} catch (Exception e) {e.printStackTrace();throw new Exception("序列化对象失败:"+String.valueOf(obj));}finally {try {if(bos!=null){bos.close();}if(oos!=null){oos.close();}} catch (IOException e) {e.printStackTrace();}}}return null;
}
(2)字符串反序列化成java对象
public static <T extends Serializable> T deserialize(String str) throws Exception{if(StringUtils.isNotEmpty(str)){ByteArrayInputStream bai=null;ObjectInputStream ois=null;try{bai=new ByteArrayInputStream(stringToByte(str));ois=new ObjectInputStream(bai);return (T)ois.readObject();}catch (Exception e){e.printStackTrace();throw new Exception("字符串反序列化对象失败:"+String.valueOf(str));}finally {try {if(ois!=null){ois.close();}if(bai!=null){bai.close();}} catch (IOException e) {e.printStackTrace();}}}return null;
}
2.4 完整工具类代码
2.4.1 maven依赖
<dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.10</version>
</dependency>
<dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>1.14</version>
</dependency>
2.4.2 java代码
package com.demo.cs.template.util;import org.apache.commons.codec.DecoderException;
import org.apache.commons.lang3.SerializationUtils;
import org.apache.commons.lang3.StringUtils;
import java.io.*;/*** 序列化工具类*/
public class SerializeUtil {/*** 字节数组转换为字符串*/public static String bytesToString(byte[] bytes) { 字符串、字节数组转换方式很多,可以根据自己的要求,自定义转换方式//转换成hex//return org.apache.commons.codec.binary.Hex.encodeHexString(bytes);//转换成base64return org.apache.commons.codec.binary.Base64.encodeBase64String(bytes);}/*** 字符串转换为字节数组* @param str* @return*/public static byte[] stringToByte(String str) throws DecoderException { 字符串、字节数组转换方式很多,可以根据自己的要求,自定义转换方式//转换成hex//return org.apache.commons.codec.binary.Hex.decodeHex(str);//转换成base64return org.apache.commons.codec.binary.Base64.decodeBase64(str);}/*** 序列化对象(依赖commons-lang3包)* @param obj 序列化对象* @return 对象序列化之后的字符串*/public static String serialize(Serializable obj) throws Exception{if(obj!=null) {byte[] bytes = SerializationUtils.serialize(obj);return bytesToString(bytes);}return null;}/*** 反序列化对象(依赖commons-lang3包)* @param str 反序列化字符串* @return 反序列化之后的对象*/public static <T extends Serializable> T deserialize(String str) throws Exception{if(StringUtils.isNotEmpty(str)){return SerializationUtils.deserialize(stringToByte(str));}return null;}
}
3 限制
3.1 序列化前置条件
java对象可序列化成字节数组的前提是:
java类必须实现序列化接口:Serializable
,此接口代表该类的实例化对象,可以进行序列化(对象内的内置属性,也需要实现此接口
)。
如不实现此接口,序列化成对象时,将抛出异常:java.io.NotSerializableException
为防止调用工具类的时候,参数未实现此接口,可在工具类指定参数
或返回值泛型
的类型:
public static String serialize(Serializable obj) throws Exception{...}public static <T extends Serializable> T deserialize(String str) throws Exception{...}
3.2 字节数组转换字符串
对象序列化后,是以字节数组的形式存在,需要将字节数组转码成可读的字符串。上面有hex和base64转码示例。
无论以哪种方式转码和反转码,均需采用一样的算法。
3.3 序列化时忽略属性
如对象属性被关键字transient
所修饰,对象序列化时,将会忽略此属性。如下:
private transient String userName;
4 扩展
4.1 hex和base64
(1)含义
java中有可见字符
和不可见字符
的区分,不可见字符在输出字符串的时候无法看到。如将字节数组
转换成字符串
,需要先根据编码规则将字节数组
转换成字符数组
,再将字符数组
转换成字符串
,由于部分转换后的字符是不可见的
,此类字符无法转换成可见的字符串,将存在数据的丢失
。在将字节数组转换成对应的字节时,hex和base64可以将不可见字符
转换成可见字符
,实现数据的二进制安全转换
。
hex和base64都是编码方式
和加密无关,将字节数组编码为可见的字符串
。
hex的意思是16进制
,编码后大小变为2倍
,一个字符用两个可见字符来表示。
base64如字面意思,64进制
来表示数组,编码后大小变成4/3
倍,3个字符用4个可见字符来表示。
(2)编码速度
hex编码解码速度比base64快,hex速度更快
。
(3)编码后大小
base64编码后字符串大小比hex小,base64占用空间更小
。
(4)转换后格式
hex编码后内容如下:
aced000573720022636f6d2e64656d6f2e63732e74656d706c6174652e6265616e2e54656d7055736572a55d364cf96782ab0200024c00036167657400134c6a6176612f6c616e672f496e74656765723b4c0008757365724e616d657400124c6a6176612f6c616e672f537472696e673b7870737200116a6176612e6c616e672e496e746567657212e2a0a4f781873802000149000576616c7565787200106a6176612e6c616e672e4e756d62657286ac951d0b94e08b020000787000000012740006e5bca0e4b889
base64编码后内容如下:
rO0ABXNyACJjb20uZGVtby5jcy50ZW1wbGF0ZS5iZWFuLlRlbXBVc2VypV02TPlngqsCAAJMAANhZ2V0ABNMamF2YS9sYW5nL0ludGVnZXI7TAAIdXNlck5hbWV0ABJMamF2YS9sYW5nL1N0cmluZzt4cHNyABFqYXZhLmxhbmcuSW50ZWdlchLioKT3gYc4AgABSQAFdmFsdWV4cgAQamF2YS5sYW5nLk51bWJlcoaslR0LlOCLAgAAeHAAAAASdAAG5byg5LiJ
4.2 base32
还有种编码方式base32,如字面意思,32进制来转码字符数组。可酌情使用
java对象序列化为字符串相关推荐
- c#将对象序列化为字符串和将字符串反序列化为对象
asp.net开发中,页面间传值最长用到的是url显式传参,session,application和cookie传值等.对于复杂对象页面传值,如果不考虑性能影响的话,通常可以使用session或者ap ...
- 将对象序列化为字符串
本文翻译自:Serialize an object to string I have the following method to save an Object to a file: 我有以下方法将 ...
- java字符串序列化_java对象序列化为字符串
1 场景 java对象某些时候,需要序列化成字符串存储在数据库中,需要的时候,再将字符串反序列化为java对象. 如使用shiro缓存分布式session,需要将session对象序列化成字符串存储在 ...
- java 嵌套对象序列化_在javascript中将复杂的,嵌套的,用户定义的对象序列化为字符串...
是的,所以's kind of like you'重新序列化对象数据,而不是类数据 . 变量仍然存在,但关于类的元数据(即方法)没有被保留 . 一个解决方案可能是serialijse . serial ...
- js对象序列化为json字符串
网上找了找将js对象序列化为json字符串的方法.结果都不近人意,最后自己写了一个. 注意你得自己为Date增加toString()方法. function Serialize(obj){switch ...
- Java对象序列化乱码6_对象序列化成字符串乱码解决
问题描述: 将一个对象序列化成字符串后,字符串是乱码的,并且反序列化报错. 代码如下: import com.alibaba.fastjson.JSONObject; import org.sprin ...
- JavaScriptSerializer-枚举的JSON序列化为字符串
我有一个包含enum属性的类,并在使用JavaScriptSerializer序列化对象后,我的json结果包含枚举的整数值,而不是其string " name". 有没有一种方法 ...
- java 序列化成xml文件_将Java对象序列化成JSON和XML格式
1.先定义一个Java对象Person: public class Person { String name; int age; int number; public String getName() ...
- qs—对象序列化为查询参数和URL解析成对象的库
安装 npm install qs 使用 let qs = require('qs') // 或者 import qs from 'qs' 方法 对象序列化为URL查询参数 let obj = {a: ...
最新文章
- mysql 自动化运维工具_MySQL使用工具Inception实现自动化运维
- 字符串模糊/精确查询——mysql
- Python网络请求urllib和urllib3详解
- 计算机网络 | 数据链路层 :ARP协议、以太网协议、MTU
- Mysql和Oracle获取自增主键
- Linux 命令之 newgrp -- 登入另一个群组
- python以20字符宽居中输出,Python 字符串内置方法(一)
- 牛客网编程题03--明明的随机数
- EMNLP2018 - 语言理解+对话系统的最新进展
- 现实世界的Windows Azure: 采访LexisNexis的Marc Slovak 和 Manish Bhargava
- 关键词词云怎么做_网友问:做独立站,怎么做关键词排名,怎么做客户流量?...
- 在pycharm中使用pyqt5时clicked().后面connect不自动补全问题解决办法
- web前端入门到实战:HTML图像标签img和源属性src及Alt属性、宽高、对齐
- 遗传算法优化BP神经网络,bp神经网络的优化算法
- detecting android sdk, Select Android SDK directory
- 阿里巴巴入选的JCP最高执行委员会,何方神圣?
- Arcgis 地理坐标系转投影坐标系(WGS84转CGCS2000)
- openwrt路由器php-cli,【在openwrt无线路由器上部署freeswitch+fusionpbx (原帖恩山论坛)】-网关论坛-ZOL中关村在线...
- element分页组件,搜索过后current-page 绑定的数据变了,但是页面当前页码并没有变的问题
- flutter CustomScrollView中使用Swiper做轮播图问题
热门文章
- Linux内核:内存从BIOS->e820->memblock->node/zone基本流程
- Linux内存管理:内存描述之内存区域zone
- linux下基于Posix message queue的同步消息队列的实现
- 【转】C++从零实现神经网络
- Python:isinstance()和type()
- net start mysql 失败_net start mysql出错,显示错误1067
- lisp如何批量选中特定图层_图层管理的奥秘
- mysql unique和key_MYSQL的primary key和unique key的区别
- mysql5.1 utf8_编译安装mysql 5.1使用utf8解决乱码问题
- 录入班级学生姓名科目成绩_如何利用钉钉发布考试成绩