今天上班摸鱼摸得正起劲,前端同事发来一条消息说调我接口时报错:
接口:
@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 的参数呢?
1
mikoshu 2019 年 8 月 29 日
get 请求传啥数组 让他直接把字符串用逗号隔开给你呗
|
2
chendy 2019 年 8 月 29 日
url 参数本身就是多值的,只不过一般用不到:n=1,2,3,4 或者 n=1&n=2&n=3&n=4
一旦要用到复杂对象结构和数组,就直接用 POST 吧,省心省事 |
3
chendy 2019 年 8 月 29 日
忘了说 n=1,2,3,4 或者 n=1&n=2&n=3&n=4 至少 SpringMVC 可以直接用数组和集合接
|
4
baronOvO 2019 年 8 月 29 日
我觉得 1 楼说的对
|
5
rzti483NAJ66l669 2019 年 8 月 29 日
路由都不规范为什么参数格式要规范呢?
|
6
me876 2019 年 8 月 29 日 让前端用 qs 库转换下后端能接收的格式就行,这个坑我之前也踩过。
``` qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'indices' }) // 'a[0]=b&a[1]=c' qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'brackets' }) // 'a[]=b&a[]=c' qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' }) // 'a=b&a=c' qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'comma' }) // 'a=b,c' ``` |
7
index90 2019 年 8 月 29 日
记得是推荐格式 1
|
9
ipwx 2019 年 8 月 29 日 via Android 批量的接口为啥不用 post
|
10
DreamSpace OP |
11
ipwx 2019 年 8 月 29 日 via Android
@DreamSpace 我个人觉得幂等性这种概念在这个例子上不重要。首先,批量接口组合数太多,基本没有 http 层缓存的价值。其次,get 参数无法应对大量 ID 的请求,还是得上 post。那些说 get 加上 body 的做法,我觉得那比违反所谓的幂等性更糟糕。综上,我觉得该用 post
|
12
wysnylc 2019 年 8 月 29 日
1 是正确的 2,3 是什么鬼
现在一般都转成 json &n=[1,2,3]这种形式传输 |
13
PerpetualHeng 2019 年 8 月 29 日
我先说第一点,从来没有 url 传参上会带上"[]"这种符号,即使是数据也是第一种方式。
第二传数组一般都是搞成 json 传,后端转一下。 涉及到这种传数组的请求,数据大小可以无限制,还是用 post 吧。 |
14
Vegetable 2019 年 8 月 29 日
|
15
DavidNineRoc 2019 年 8 月 29 日
多年的经验
1 肯定是不行的,参数后面的会覆盖前面的值 2,3 都行,因为不写索引,会类似 js 的数组,索引会自增。 ***** 说 2,3 不行的,表单字段数组类型的没用过? 代码已复制,请直接使用 <!DOCTYPE HTML> <html lang="en-US"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <form action=""> <input type="text" name="tags[]" /> <input type="text" name="tags[]" /> <input type="text" name="tags[]" /> <input type="text" name="tags[]" /> <button type="submit">提交</button> </form> </body> </html> |
16
DavidNineRoc 2019 年 8 月 29 日
之所以不行的原因,多半是因为你前端对象没有 urlencode 吧
|
17
TabGre 2019 年 8 月 29 日 via iPhone
6 楼说的有道理,前端可以自己拼接成你可以解析的形式,手动或者 qs 库
|
18
Sparetire 2019 年 8 月 29 日 via Android
都可以,事实上就 HTTP 而言并没有限制你用哪种,甚至也不需要是 key=value 这样的格式,也都是合法的,这些格式都是框架的约定而已
所以后端能处理哪种就传哪种就行了 |
19
LokiSharp 2019 年 8 月 29 日
get 也可以带 body 的啊
|
20
whitev2 2019 年 8 月 29 日
@Vegetable #14 A payload within a GET request message has no defined semantics;
sending a payload body on a GET request might cause some existing implementations to reject the request.没有说不行,只是服务端可能不拿来用而已 |
21
Vegetable 2019 年 8 月 29 日 @DavidNineRoc 1 是可以的,不会覆盖,世界上不是只有你一个明白人。
|
22
MonoLogueChi 2019 年 8 月 29 日 via Android
我以前也写过数组,感觉 1 用的比较多,在网上也看过别人用 2 和 3 这种,我自己也用过 1 这种格式。另外路由写好了怎么搞都可以,比如 a.com/api/query/300,301,302,303,使用后面这种格式的时候,fetch 请求特别的方便。
springboot 没用过,我也不知道怎么搞才能支持后面的,感觉这种东西应该尽量让前端去修改请求,而不是后端修改接口 |
24
azh7138m 2019 年 8 月 29 日 |
25
willxiang 2019 年 8 月 29 日
直接 24L 连接里选“?list=red,green,blue ”这种不是一目了然了吗,后端拿到直接逗号分割
|
26
SoloCompany 2019 年 8 月 29 日
以 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 我暂时没见过哪个框架会使用 |
27
momocraft 2019 年 8 月 29 日
复杂参数没有规范
我记得 rfc 连 uri query 的严格定义都无 |
28
x66 2019 年 8 月 29 日
URL 都不标准,为何这么在意参数,用 POST 大法好
|
29
xiangyuecn 2019 年 8 月 29 日
各位大佬,请教一下,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) |
30
chocotan 2019 年 8 月 29 日
错误提示里规范都出来了,很显然是没有 urlencode
|
31
quericy 2019 年 8 月 29 日 |
33
w516322644 2019 年 8 月 29 日
我记得 1 被覆盖过啊。
后来就是 2 那种 |
34
w516322644 2019 年 8 月 29 日
@willxiang 这种唯一问题,就是怕字符串有,
|
35
dany813 2019 年 8 月 29 日
用 qs 库吧
|
36
lululau 2019 年 8 月 29 日 via iPhone
第一种是 servlet 支持的,springmvc 三种都可以
|
37
no1xsyzy 2019 年 8 月 30 日
这么烦直接 jsonrpc 好不好啊
|
38
zjyl1994 2019 年 8 月 30 日
我们一般用的都是逗号分隔的字符串
|
39
luozic 2019 年 8 月 30 日
为啥不 urlencode,服务端获取的请求到底长啥样?
|