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

前言
温馨提示:可以订阅我的微信公众号,在手机里看技术文档也很不错哦o( ̄︶ ̄)o

本篇文章主要说下接口的数据参数到底该如何接收,我们知道一个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)被舍弃掉了。

解决方式是:

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请求的接口调用日志)。
  • ②. 我们可以通过这些参数信息处理我们的业务逻辑,而没有必要在用到的时候我们才想起来让调用者将信息传递过来,导致同一功能性的参数,参数名和参数值不统一的情况发生。
  1. 是每个接口都要这些参数么?
    是的,建议将所有的接口都传递上述参数信息。
  2. 怎么做这些参数的校验呢?
    你可以写个拦截器,统一校验你的接口中全局的header参数,如果还是不太会写,可以参考这篇文章《统一参数校验》

备注

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

请求体参数

参数传递分为了大体两种 URL请求查询参数、请求体参数,对于请求体参数我们选择以JSON格式传递过来,URL请求查询参数、请求体参数这两种方式分别对应了spring mvc框架中的 @RequestParam、@RequestBody两个注解进行修饰。
我们下面以添加一个用户举例,用POST MAN截图如下:

举例
Restful Api写法心得之二《参数接收篇》_第1张图片

开发实例

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体参数。

备注

  • 在实际开发中我们可能会遇到跨域问题,开发环境中我们会自定义拦截器(AllowCrossDomainInterceptor)处理这种情况,可以看下我的这篇文章《企业实战之拦截器解决跨域问题》。

结束语

下一篇文章我们主要讲解下 《接口返回值篇》 O(∩_∩)O

源码github地址:https://github.com/zhumaer/zhuma
QQ群号:629446754(欢迎加群)

欢迎关注我们的公众号或加群,等你哦!

Restful Api写法心得之二《参数接收篇》_第2张图片

Restful Api写法心得之二《参数接收篇》_第3张图片

你可能感兴趣的:(Resetful,Api心得整理,Spring企业实战)