uniquejava / blog

My notes regarding the vibrating frontend :boom and the plain old java :rofl.
Creative Commons Zero v1.0 Universal
11 stars 5 forks source link

vue axios send json body + spring boot #276

Open uniquejava opened 4 years ago

uniquejava commented 4 years ago
  1. 我想用axios.get(url, options)send json数据到后端
  2. 在spring boot @RestController中取到它.
  3. 一贯的风格: 代码要极简
uniquejava commented 4 years ago

首先要明白, axios通过body传参是这样的:

axios.get(url, {data: {key: value}})

axios通过query string传参是这样的:

axios.get(url, {params: {key: value}})

前端坑1: 本来HTTP规范中 GET是可以传body的, 但是呢前端底层用到的XHR会丢弃body, 所以排除 data: {key:value} 的选项. 使用 {params: {key: value}})

前端坑2: {params: {key: value}}, axios支持stringify简单的JSON对象, 如果JSON中有nested object, 比如{a: {b: 'c'}, 你想转成a.b=c, 对不起, axios不支持. 所以找个第三方库. 结论是使用qs

再来说spring boot, 如果前端通过http body传参. spring boot有对应的 @RequestBody MyInput input, 相当的好理解.

但是如果前端是通过query string如?a=1&b=2&c=3, spring boot有对应的 @RequestParam String a, @RequestParam String b ...

有强迫症的会觉得. 这参数也太多了. 能不能通过单个对象一下子接收. 答案是肯定的.

  1. 前端URL拼参input.a=1&input.b=2&input.c=3 a=1&b=2&c=3
  2. 后端spring boot不用加任何注解, 就这样 methodXxx(MyInput input)

最终的代码如下:

async loadSomeStuff() {
       // const params = { input: { a: 1, b:2, c:3 } }
      const params = {a: 1, b:2, c:3}
      // const query = qs.stringify(params, { allowDots: true })
      // const res = await http.get(`/api/niubilities?${query}`))
      const res = await http.get(`/api/niubilities`, { params }))
 }
@GetMapping
public ApiReponse<MyOutput> query(MyInput input) {
...
}

关于axios.get不能通过body传参的问题, 这里 https://github.com/axios/axios/issues/787 有激烈的讨论. 里边不伐很多不懂到底什么是通过http body传参的人贴出来诸如 {params: {key: value}}) 这样的代码, 其实只要出现params, 就不是通过http body!

spring boot如何通过单一对象接收参数, 来自这里: How to bind @RequestParam to object in Spring | Dev in Web