文章目录
- 1 摘要
- 2 几种后台接口参数接收方案
- 2.1 使用 map 作为参数接收对象
- 2.2 统一使用实体类接收
- 2.3 每一个接口使用一个与之对应的参数接收对象
- 3 接口参数接收与校验推荐示例
- 3.1 接口请求参数对象
- 3.2 Controller 层的参数校验
1 摘要
在前后端分离的大前提下,Java 后台接口请求参数规范在项目开发过程中就变得非常重要。前端开发需要根据接口文档来对接调试,后台开发也能够根据快速定位接口所需的参数,尤其是在新接手项目的时候。问题排查、项目架构调整等等都需要明确知晓每一个接口的所需参数以及对应的校验。
2 几种后台接口参数接收方案
2.1 使用 map 作为参数接收对象
优点: 传参数方便,前端什么参数都可以传,后台只需根据所需字段进行获取即可
缺点: 请求参数的字段比较模糊,难以知晓每个接口所需要的具体字段。同时不能通过 Swagger 生成接口文档。后期维护困难。
结论: 不建议使用。
2.2 统一使用实体类接收
使用某一模块的实体类接收该模块的所有接口。
优点: 可以使代码相对简洁,能够使用 Swagger 生成接口文档,并且能够对字段添加对应的校验。
缺点: 对于同一个字段,不同的接口使用的校验可能不同,使用同一个对象来接受,不利于参数校验。使用 Swagger 生成接口文档后字段的校验不准确。后台维护时不能直观知晓每个接口所需字段以及校验,后期维护困难。
结论: 如果某一个模块只有一个接口,可以选择实体类作为接口参数接收对象。如果接口较多,且对于同一个字段存在不同的校验,则不推荐使用。
2.3 每一个接口使用一个与之对应的参数接收对象
优点: 可以实现使用 Swagger 生成接口文档,前后端能够清晰知晓每个接口所需字段,以及每个字段对应的校验。字段校验灵活,可以实现不同的接口对于同一个字段的不同校验。
缺点: 每新增一个接口,需要写一个对应的接口参数接收对象,增加代码量。
结论: 虽然代码量有所增加,但是对于前后端调试以及后期维护而言,却极大地方便。
3 接口参数接收与校验推荐示例
3.1 接口请求参数对象
./src/main/java/com/ljq/demo/springboot/mybatisplus/model/param/user/UserSaveParam.java
package com.ljq.demo.springboot.mybatisplus.model.param.user;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import java.io.Serializable;
/**
* 用户表参数接收类
*
* @author junqiang.lu
* @date 2020-08-31 14:09:53
*/
@Data
@ApiModel(value = "用户表保存(单条)", description = "用户表保存(单条)")
public class UserSaveParam implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 用户名
* */
@NotBlank(message = "用户名 不能为空")
@Length(max = 40, message = "用户名需要控制在 40 字符以内")
@ApiModelProperty(value = "用户名", name = "userName", required = true)
private String userName;
/**
* 登陆密码
* */
@NotBlank(message = "登陆密码 不能为空")
@Length(max = 40, message = "密码长度需要控制在 40 字符以内")
@ApiModelProperty(value = "登陆密码", name = "userPasscode", required = true)
private String userPasscode;
/**
* 邮箱
* */
@NotBlank(message = "邮箱 不能为空")
@Email(message = "邮箱格式错误")
@ApiModelProperty(value = "邮箱", name = "userEmail", required = true)
private String userEmail;
}
./src/main/java/com/ljq/demo/springboot/mybatisplus/model/param/user/UserUpdateParam.java
package com.ljq.demo.springboot.mybatisplus.model.param.user;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.Email;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* 用户表参数接收类
*
* @author junqiang.lu
* @date 2020-08-31 14:09:53
*/
@Data
@ApiModel(value = "用户表修改(单条)", description = "用户表修改(单条)")
public class UserUpdateParam implements Serializable {
private static final long serialVersionUID = 1L;
/**
* id 主键
* */
@NotNull(message = "id 主键 不能为空")
@Min(value = 1, message = "id 主键 至少为 1")
@ApiModelProperty(value = "id 主键 不能为空,至少为 1", name = "id", required = true, example = "0")
private Long id;
/**
* 用户名
* */
@Length(max = 40, message = "用户名需要控制在 40 字符以内")
@ApiModelProperty(value = "用户名", name = "userName", required = true)
private String userName;
/**
* 登陆密码
* */
@Length(max = 40, message = "密码长度需要控制在 40 字符以内")
@ApiModelProperty(value = "登陆密码", name = "userPasscode", required = true)
private String userPasscode;
/**
* 邮箱
* */
@Email(message = "邮箱格式错误")
@ApiModelProperty(value = "邮箱", name = "userEmail", required = true)
private String userEmail;
}
常用校验注解
javax.validation.constraints.NotNull
: 非空校验
javax.validation.constraints.NotBlank
: 字符串非空校验
javax.validation.constraints.NotEmpty
: 数组、列表的非空校验
javax.validation.constraints.Min
: 最小值校验,作用于数值型对象
javax.validation.constraints.Max
: 最大值校验,作用于数值对象
javax.validation.constraints.Size
: 尺寸校验,作用于数组、列表
javax.validation.constraints.Email
: 邮箱地址校验,校验字符串是否符合邮箱规则
javax.validation.constraints.Pattern
: 自定义正则校验
org.hibernate.validator.constraints.Length
: 校验字符串长度
javax.validation.Valid
: 校验标识,表名该对象进行参数校验
3.2 Controller 层的参数校验
./src/main/java/com/ljq/demo/springboot/mybatisplus/controller/UserController.java
package com.ljq.demo.springboot.mybatisplus.controller;
import com.ljq.demo.springboot.mybatisplus.common.api.ApiResult;
import com.ljq.demo.springboot.mybatisplus.model.param.user.*;
import com.ljq.demo.springboot.mybatisplus.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
/**
* 用户表
*
* @author junqiang.lu
* @date 2020-08-31 16:39:56
*/
@Slf4j
@RestController
@RequestMapping(value = "/api/mybatis/plus/user")
@Api(value = "用户表控制层", tags = "用户表控制层")
public class UserController {
@Autowired
private UserService userService;
/**
* 保存(单条)
*
* @param userSaveParam
* @return
*/
@PostMapping(value = "/add", produces = {MediaType.APPLICATION_JSON_VALUE})
@ApiOperation(value = "用户表保存(单条)", notes = "用户表保存(单条)")
public ResponseEntity<?> save(@Validated @RequestBody UserSaveParam userSaveParam) throws Exception{
ApiResult apiResult = userService.save(userSaveParam);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return new ResponseEntity<>(apiResult, headers, HttpStatus.OK);
}
/**
* 修改(单条)
*
* @param userUpdateParam
* @return
*/
@PutMapping(value = "/update", produces = {MediaType.APPLICATION_JSON_VALUE})
@ApiOperation(value = "用户表修改(单条)", notes = "用户表修改(单条)")
public ResponseEntity<?> update(@Validated @RequestBody UserUpdateParam userUpdateParam) throws Exception {
ApiResult apiResult = userService.update(userUpdateParam);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return new ResponseEntity<>(apiResult, headers, HttpStatus.OK);
}
}
推荐使用 Spring 的 @Validated
注解对请求参数进行校验
@Valid
不支持分组校验, @Validated
支持分组校验(虽然不推荐使用)