当前位置:网站首页>记录PHPSerializer工具类反序列化遇到的坑
记录PHPSerializer工具类反序列化遇到的坑
2022-07-24 05:27:00 【cxcaln】
php语言中,有自己封装好的序列化跟反序列化的方法,如果我们在java项目中需要反序列化由php序列化的数据,我们可以使用PHPSerializer工具类
pom文件中引入依赖
<!-- 反序列化php序列化过的字符串 -->
<dependency>
<groupId>org.sction</groupId>
<artifactId>phprpc</artifactId>
<version>3.0.2</version>
</dependency>使用也非常简单,由于序列化的数据大多数是json,该工具会反序列化成AssocArray类对象,所以写法如下:
public static AssocArray unSerializePhpStr(String str) throws InvocationTargetException, IllegalAccessException {
if(StringUtils.isEmpty(str)) {
return null;
}
PHPSerializer p = new PHPSerializer();
return (AssocArray) p.unserialize(str.getBytes());
}我们反序列化一个简单的json字符串:a:1:{i:123;s:2:"id"}
String str = "a:1:{i:123;s:2:\"id\"}";
AssocArray object = PhpSerializerUtil.unSerializePhpStr(str);
HashMap hashMap = object.toHashMap();
反序列化成功了,我们可以使用toHashMap()将AssocArray对象转成HashMap对象
但是这只是简单的json反序列化,php在序列化的时候,数字类型都会序列化成i类型,而在java中会区分int和long类型,所以如果数值太大,在java中会反序列化失败,比如:
a:2:{i:1;i:1649729539760;s:2:"id";i:2;}
我们反序列化一下试试

发现直接报错,我们去看一下源码:
这里可以看到,i类型直接会映射成Integer,所以长度会有限制。我们再仔细看,发现有个d类型可以映射成Double,那我们将i全部改成d试试
str.replaceAll("i:","d:");再试一下

发现返回的直接是null,虽然没报错,但是明显不对,我们再看看源码:

i跟d的映射应该没有问题,问题出现在a上面,我们进去看看

json是<k,v>结构,可以看到AssoArray对象的key并不支持Double类型,所以直接返回了null,所以只能将value类型由i转成d,key不能改,但是反序列化之后的字符串特别难区分key和value,写起来很麻烦,所以干脆,直接将i类型转成s(String),这样key和value都支持
public static AssocArray unSerializePhpStr(String str) throws InvocationTargetException, IllegalAccessException {
if(StringUtils.isEmpty(str)) {
return null;
}
//整形全部转成字符串,避免长度超出(key不支持其他数字类型)
String numStr = "i:";
while (str.contains(numStr)) {
int index = str.indexOf(numStr);
String str1 = str.substring(0,index);
String str2 = str.substring(index);
int index1 = str2.indexOf(";");
str = String.format("%ss:%d:\"%s\"%s",str1,index1-2,str2.substring(2,index1),str2.substring(index1));
}
PHPSerializer p = new PHPSerializer();
return (AssocArray) p.unserialize(str.getBytes());
}我们再试试:

发现成功了
注意:AssocArray对象中的字符串类型value全都是byte数组,需要自己手动转成String
补充:AssocArray对象处理起来太麻烦,补充一个返回json的方法
/**
* 将所有的AssocArray转成java
* @param str
* @return
* @throws InvocationTargetException
* @throws IllegalAccessException
*/
public static JSONObject unSerializePhpStrBackJson(String str) throws InvocationTargetException, IllegalAccessException {
AssocArray assocArray = unSerializePhpStr(str);
return assocArrayToHash(assocArray);
}
private static JSONObject assocArrayToHash(AssocArray assocArray) {
HashMap hashMap = assocArray.toHashMap();
JSONObject result = new JSONObject();
for (Object key : hashMap.keySet()) {
if(hashMap.get(key) instanceof AssocArray) {
result.put(key.toString(),assocArrayToHash((AssocArray) hashMap.get(key)));
}else if(hashMap.get(key) instanceof byte[]) {
result.put(key.toString(),new String((byte[]) hashMap.get(key)));
}else {
result.put(key.toString(),hashMap.get(key));
}
}
return result;
}边栏推荐
猜你喜欢

Grid layout

Learn more about when to use MySQL two locks (table lock and row lock)

Secondary processing of template data

kubernetes简介和架构及其原理

Take you to understand the inventory deduction principle of MySQL database

Transition effect

Customize MVC 3.0

Special effects - when the mouse moves, stars appear to trail

Flex layout

基于回归分析的广告投入销售额预测——K邻近,决策树,随机森林,线性回归,岭回归
随机推荐
Yiwen node installation, download and configuration
文件系统与日志分析
Special effects - click with the mouse and the fireworks will burst
Go environment construction and start
带你深入了解MySQL数据库扣减库存原理
Customize ZABBIX agent RPM package
Jmeter分布式压测
MySQL batch modifies the data table code and character set to utf8mb4
Install Apache manually
File system and log analysis
使用自定义zabbix包(4.0.5版本)安装agent和proxy
STM32基于 FatFs R0.14b&SD Card 的MP3音乐播放器(也算是FatFs的简单应用了吧)
Sort by an attribute value of an object in the array
中药材的鉴别
机器学习案例:孕妇吸烟与胎儿健康
SSH远程访问及控制
【LVGL(6)】显示中文设置,制作中文字库
实验:LVM逻辑卷的建立、扩容、与删除
System safety and Application
awk的使用