Restful Api写法心得之二《参数接收篇》

原文地址:Restful Api写法心得之二《参数接收篇》

原文作者:筑码-井哥

本篇文章主要说下接口的数据参数到底该如何接收,我们知道一个http请求最重要的意义就是将数据在服务器上进行传入与传出,本章主要讲的也就是传入。一次请求传递参数的方式主要有 URL路径中、请求头中、请求体中还有通过cookie等,下面我们分别对几种方式进行讲解。

MediaType的选择

MediaType即是Internet Media Type,互联网媒体类型;也叫做MIME类型,在Http协议消息头中,使用Content-Type来表示具体请求中的媒体类型信息。

  • 对于POST、PUT、PATCH这种HTTP方法,统一使用 application/json,将参数放在请求体中以JSON格式传递至服务器
  • 对于GET、DELETE的HTTP方法,使用默认类型(application/x-www-form-urlencoded)

备注

特殊情况特殊考虑,例如进行文件上传时,使用 multipart/form-data类型等

路径参数

对应spring mvc框架中@PathVariable注解

★备注

这里有个注意的点,当路径参数值中有带点”.”的情况时,spring mvc框架中有对点做特殊处理,这导致在程序中只能接收到点之前的内容,例如你的请求是:GET https://api.zhuma.com/users/hehe.haha,后端在接收userId=’hehe.haha’时,只会接收到hehe字符串,后面的部分(.haha)被舍弃掉了。

解决方式是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.zhuma.demo.analyst.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {

@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseSuffixPatternMatch(false);//可以让URL路径中带小数点 '.' 后面的值不被忽略
}

}

请求头参数

对应spring mvc框架中@RequestHeader注解

对于提供给APP(android、ios、pc) 的接口我们可能需要关注一些调用信息,例如 用户登录信息、调用来源、app版本号、api的版本号、安全验证信息 等等,我们将这些信息放入头信息(HTTP HEAD中),下面给出在参数命名的例子:

  • X-Token 用户的登录token(用于兑换用户登录信息)
  • Api-Version api的版本号
  • App-Version app版本号
  • Call-Source 调用来源(IOS、ANDROID、PC、WECHAT、WEB)
  • Authorization 安全校验参数(后面会有文章详细介绍该如何做安全校验)
    这时你可能会思考一下几个问题:
  1. 为什么需要收集 api版本号、app版本号、调用来源这些信息呢?
    这里解释下,主要有几个原因:

    ①. 方便线上环境定位问题,这也是一个重要的原因(我们后面会讲通过切面全局打印非GET请求的接口调用日志)。

    ②. 我们可以通过这些参数信息处理我们的业务逻辑,而没有必要在用到的时候我们才想起来让调用者将信息传递过来,导致同一功能性的参数,参数名和参数值不统一的情况发生。

  2. 是每个接口都要这些参数么?
    是的,建议将所有的接口都传递上述参数信息。

  3. 怎么做这些参数的校验呢?

    你可以写个拦截器,统一校验你的接口中全局的header参数,如果还是不太会写,可以参考这篇文章《统一参数校验》

备注

  • Header参数大小写不敏感,所以参数X-Token和X-TOEKN是一个参数

请求体参数

参数传递分为了大体两种 URL请求查询参数、请求体参数,对于请求体参数我们选择以JSON格式传递过来,URL请求查询参数、请求体参数这两种方式分别对应了spring mvc框架中的 @RequestParam、@RequestBody两个注解进行修饰。

我们下面以添加一个用户举例,用POST MAN截图如下:

举例

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
package com.zhuma.demo.user.web;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.zhuma.demo.comm.model.po.User;
import com.zhuma.demo.user.service.user.UserService;
import com.github.pagehelper.PageInfo;

/**
* 用户管理控制器
*/
@RestController
@RequestMapping("/users")
public class UserController {

private final UserService userService;

@Autowired
public UserController(UserService userService) {
this.userService = userService;
}

@GetMapping
public PageInfo<User> getUserList(@RequestParam(name="pageNum", defaultValue="1") Integer pageNum,
@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
@RequestParam(name="queryUser") User queryUser) {
return userService.pageList(queryUser, pageNum, pageSize);
}

@GetMapping("/{userId}")
User getUser(@PathVariable("userId") Long userId) {
return userService.getUserById(userId);
}

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public User addUser(@Valid @RequestBody User user) {
return userService.register(user);
}

@PutMapping
public User updateUser(@RequestBody User user) {
return userService.updateDbAndCache(user);
}

@DeleteMapping("/{userId}")
@ResponseStatus(HttpStatus.NO_CONTENT)
void deleteUser(@PathVariable("userId") Long userId) {
userService.deleteUserById(userId);
}

}

上面我们截取一个管理用户的功能控制器,可能其中有一些你不了解的注解,例如@Valid、@ResponseStatus我们后面会讲解,所以你可以先不必关注这些,我们主要看@GetMapping、@PostMapping、
@PutMapping、@DeleteMapping 分别处理查、修改、删除功能,@RequestParam、@RequestBody 分别表示
查询参数、json body体参数。

备注

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2015-2023 高行行
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信