Java在HTTP请求中传递数组参数的方法

有个功能需要我请求别人提供的接口,该接口的参数是一个多维数组,大致类似这样:

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
$array = array(
"stock_code" => "600000",
"fixed_indexes" => array(
954,
1214
),
"filters" => array(
array(
"name" => "sort",
"params" => array(
"item" => "rank",
"type" => "asc"
)
),
array(
"name" => "quantity",
"params" => array(
"operator" => ">",
"operands" => array(
"trade_couont_1",
10
)
)
),
)
);

一开始我准备将参数处理成JSON字符串传递过去,结果发现对方根本就不支持JSON字符串形式的参数。

然后又改为使用LinkedMultiValueMap,还是不行,发现这个Map要求每个值都必须是String类型,否则在后续的转换中就会出错(程序最终会将map的值都当成String来使用,进行一次强转)。

这样折腾了半天,自己都是在靠蒙来解决问题,没什么进展。这种急于求成的心态是不行的,因此停了下,准备先通过之前调用过这个接口的程序,抓个请求包,看看具体请求发送出去的参数到底是什么格式的,能否我直接按照最终的请求包格式来拼接参数。

通过tcpdump在服务器上抓了个包:

1
tcpdump -i eth1 tcp and port 80 -s 0 -w poi.cap

然后在本地通过wireshark进行查看,发现请求信息如下:

1
2
3
4
5
6
7
8
Host: zbpc.10jqka.com.cn
Connection: close
Accept-encoding: gzip, deflate
User-Agent: Zend_Http_Client
Content-Type: application/x-www-form-urlencoded
Content-Length: 491

stock_code=600000&filters%5B0%5D%5Bname%5D=sort&filters%5B0%5D%5Bparams%5D%5Bitem%5D=rank&filters%5B0%5D%5Bparams%5D%5Btype%5D=asc&filters%5B1%5D%5Bname%5D=quantity&filters%5B1%5D%5Bparams%5D%5Boperator%5D=%3E&filters%5B1%5D%5Bparams%5D%5Boperands%5D%5B0%5D=trade_count_1&filters%5B1%5D%5Bparams%5D%5Boperands%5D%5B1%5D=10&filters%5B2%5D%5Bname%5D=pagination&filters%5B2%5D%5Bparams%5D%5Bcount%5D=21&filters%5B2%5D%5Bparams%5D%5Boffset%5D=0&fixed_indexes%5B0%5D=954&fixed_indexes%5B1%5D=1214

请求的参数经过urldecode后,是这样的:

1
stock_code=600000&filters[0][name]=sort&filters[0][params][item]=rank&filters[0][params][type]=asc&filters[1][name]=quantity&filters[1][params][operator]=>&filters[1][params][operands][0]=trade_count_1&filters[1][params][operands][1]=10&filters[2][name]=pagination&filters[2][params][count]=21&filters[2][params][offset]=0&fixed_indexes[0]=954&fixed_indexes[1]=1214

到这里就比较明确了,那么我只需要将请求的Content-Type设置为表单,然后将参数拼接成上面的这种格式即可。

修改后,程序可以正常运行了。

总结:解决问题不要靠蒙,急于求成有时候反而让你效率更低。