关于 GET 请求中的数组格式

2019-08-29 11:13:15 +08:00
 DreamSpace

今天上班摸鱼摸得正起劲,前端同事发来一条消息说调我接口时报错:

接口:

    @GetMapping(value = "/getList")
    public ResponseMessage getList(IpcDeviceQuery query);

参数:

	/getList?groupIdList[]=2&groupIdList[]=3

报错:

	Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986

粗略看了一下,是 GET 请求中数组格式的问题,前端同事使用的格式并不能被 Springboot 的后端接收到。

网上查了查资料,发现 GET 请求传输数组参数的方式百花齐放,各种格式都有,归纳了一下,大概以下三种格式:

哪一种格式是真正符合规范的? Spring 需要定制什么才能解析格式 2 和格式 3 的参数呢?

14102 次点击
所在节点    Java
39 条回复
Vegetable
2019-08-29 14:53:41 +08:00
@DavidNineRoc 1 是可以的,不会覆盖,世界上不是只有你一个明白人。
MonoLogueChi
2019-08-29 15:05:57 +08:00
我以前也写过数组,感觉 1 用的比较多,在网上也看过别人用 2 和 3 这种,我自己也用过 1 这种格式。另外路由写好了怎么搞都可以,比如 a.com/api/query/300,301,302,303,使用后面这种格式的时候,fetch 请求特别的方便。

springboot 没用过,我也不知道怎么搞才能支持后面的,感觉这种东西应该尽量让前端去修改请求,而不是后端修改接口
sujin190
2019-08-29 15:36:11 +08:00
@whitev2 #20 但是浏览器包括大部分的库实现都会忽略 GET 请求中发送的 body,所以,协议说可以并没有什么用,还是得看现实啊
azh7138m
2019-08-29 15:46:35 +08:00
@DavidNineRoc
1 必然受到支持
https://tools.ietf.org/html/rfc6570#section-3.2.8

我推荐 2,解析不了就是后端太蔡了(
willxiang
2019-08-29 16:20:24 +08:00
直接 24L 连接里选“?list=red,green,blue ”这种不是一目了然了吗,后端拿到直接逗号分割
SoloCompany
2019-08-29 16:29:42 +08:00
以 jquery 为例子

假设请求为: {a:{one:1, two:2, three:3}, b:[1,2,3]}
需要 uri encode

那么
传统风格编码为: a=[object+Object]&b=1&b=2&b=3
即 格式 1
因为传统风格并不支持 object 嵌套, a 会被 to string 然后丢失信息

后来改进的风格编码为
a[one]=1&a[two]=2&a[three]=3&b[]=1&b[]=2&b[]=3
即 格式 2

格式 3 我暂时没见过哪个框架会使用
momocraft
2019-08-29 16:37:07 +08:00
复杂参数没有规范
我记得 rfc 连 uri query 的严格定义都无
x66
2019-08-29 17:09:21 +08:00
URL 都不标准,为何这么在意参数,用 POST 大法好
xiangyuecn
2019-08-29 17:26:33 +08:00
各位大佬,请教一下,Map<String,String> 接口有没有实现了多值的字典类呀? C# 有 NameValueCollection,java 不知道是哪个类,注意:是<String,String> 不是<String, List<String>>哦


因为至今没有学会如何生成一个正常的 Android WebView 响应 WebResourceResponse,因为它的一个参数 Map<String, String> responseHeaders 我不知道用什么类的实例去填 😂😂😂😂

典型的根请求参数一样,这是一个多值的问题,比如 Set-Cookie 响应头就见得多的是很多个

https://developer.android.google.cn/reference/android/webkit/WebResourceResponse.html#WebResourceResponse(java.lang.String,%20java.lang.String,%20int,%20java.lang.String,%20java.util.Map%3Cjava.lang.String,%20java.lang.String%3E,%20java.io.InputStream)
chocotan
2019-08-29 17:35:47 +08:00
错误提示里规范都出来了,很显然是没有 urlencode
quericy
2019-08-29 18:09:48 +08:00
不建议用格式 1,不同语言和容器对同名参数的默认处理方式可能会不一样。
如果无法确保服务端配置合理的话,可能会有 HTTP 参数污染(HPP)攻击的风险
Alexhohom
2019-08-29 18:43:16 +08:00
@Vegetable 不会覆盖,那用什么方法取值呢?需要自写解析函数吗?
w516322644
2019-08-29 18:45:04 +08:00
我记得 1 被覆盖过啊。
后来就是 2 那种
w516322644
2019-08-29 18:47:58 +08:00
@willxiang 这种唯一问题,就是怕字符串有,
dany813
2019-08-29 19:56:49 +08:00
用 qs 库吧
lululau
2019-08-29 20:00:35 +08:00
第一种是 servlet 支持的,springmvc 三种都可以
no1xsyzy
2019-08-30 10:06:35 +08:00
这么烦直接 jsonrpc 好不好啊
zjyl1994
2019-08-30 11:33:12 +08:00
我们一般用的都是逗号分隔的字符串
luozic
2019-08-30 12:54:44 +08:00
为啥不 urlencode,服务端获取的请求到底长啥样?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/596134

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX