最近项目需要做一个java版本的demo,简单来做就是按照api文档拼装请求报文请求自己的服务端,收到应答报文后做MD5签名验证等后续处理。由于客户端和服务端之前通讯报文是json格式的,那么就会涉及到json报文的生成和解析。网上找了下,貌似阿里巴巴的fastjson
库评价不错,所以就直接拿过来用了。
1 与实际的偏差
fastjson
封装的api函数倒是蛮简单的,直接拿过来就可以上手用了。但是demo程序在对服务端返回的报文做验签的时候总是通不过,后面把原始的待签报文和服务器的待签报文一对比发现两者不一致,这样验签肯定是失败的。
那问题就出在这个原始的待签报文为什么会被改变的环节了:用fastjson
从json格式的应答报文中获取的这个待签报文被重新排序了(见小节2中的json_order_is_changed
函数)。
在查过资料后,原来是fastjson
包中的JSONObject
对象中,如果直接使用parseObject
方法,可能会导致json数据重新排序。这个问题可以通过使用com.alibaba.fastjson.parser.Feature
包解决,但是需要使用最新的fastjson
包。
2 示例程序
由于demo中的业务代码过长,这里把关键的json报文解析的这一部分抽出来做了个演示程序。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 | import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import java.util.LinkedHashMap;
/**
* File: fastjsonParseMain.java
* Description: 使用 fastjson 解析json中的键值:乱序和原样输出
* Refer: 最新的fastjson包可以到官网 https://github.com/alibaba/fastjson/releases 去下载。
* (c) 2019.01.22 vfhky https://typecodes.com/java/fastjsonorder1.html
*/
public class fastjsonParseMain {
public fastjsonParseMain(){
}
/**
* 使用 fastjson 根据输入的key原样获取json中对应的值。
*
* @param s_json_data json字符串
* @param s_key json字符串中的key
* @return value key对应的value
*/
public static String json_order_not_change(String s_json_data, String s_key) {
// 1.2.54版本的fastjson包测试通过
LinkedHashMap<String, Object> json = JSON.parseObject(s_json_data, LinkedHashMap.class, Feature.OrderedField);
JSONObject jsonObject=new JSONObject(true);
jsonObject.putAll(json);
if( null == json.get(s_key) ) {
return "";
} else {
return json.get(s_key).toString();
}
}
/**
* 使用 fastjson 根据输入的key获取json中对应的值(可能会被排序)。
*
* @param s_json_data json字符串
* @param s_key json字符串中的key
* @return value key对应的value
*/
public static String json_order_is_changed(String s_json_data, String s_key){
JSONObject object=JSONObject.parseObject(s_json_data);
if( null == object.getString(s_key) ) {
return "";
} else {
return object.getString(s_key).toString();
}
}
public static void main(String[] args){
String s_org_buff = "{\"cmd_1\":1, \"cmd_2\":2, \"biz_content\":{\"aa\":\"11\",\"cb\":\"55\",\"11\":\"66\"}}";
String s_dst_buff = "";
System.out.println("==================== 原始json字符串 ===================");
System.out.println("s_org_buff=[" + s_org_buff + "].\n");
System.out.println("==================== 获取的value可能是乱序的 ===================");
s_dst_buff = fastjsonParseMain.json_order_is_changed( s_org_buff, "biz_content" );
System.out.println("s_dst_buff=[" + s_dst_buff + "].\n");
System.out.println("==================== 原样输出对应的 value 值 ====================");
s_dst_buff = fastjsonParseMain.json_order_not_change( s_org_buff, "biz_content" );
System.out.println("s_dst_buff=[" + s_dst_buff + "].\n");
}
}
|
3 使用eclipse编译执行
上面代码json_order_not_change
函数通过Feature
参数使得解析json数据的时候能够保持原样,而json_order_is_changed
函数中获取的value值可能会是排序后的数据。
两者的效果如下图所示:
Comments »