常见的请求参数的处理
body
entity作为参数(后续开发不推荐)
注意
为什么不推荐直接用 Entity 接收前端 Body?
字段泄露风险 Entity 里面可能存在敏感字段:
password、secret、deleteTime、version(乐观锁)、createBy、updateTime前端如果传了这些字段,后端会直接接收,一不小心就被篡改数据库值!例如:前端偷偷传id:999、deleted:1,直接修改别的数据或者逻辑删除前端参数和数据库字段强耦合 数据库一改字段(改名字、新增字段),接口入参跟着变,前端也要改。 有时候接口不需要 entity 全部字段,只需要其中几个。
Entity 一般有 MybatisPlus 注解(@TableName、@TableField) 虽然 jackson 反序列化不受影响,职责混乱:Entity = 映射数据库 DTO = 接收前端请求 / 返回给前端
场景:新增和修改共用一个 Entity,新增不能传 id,但 Entity 里有 id 字段,很容易出问题
当前端使用POST和PUT的请求体提交json格式的参数时,后端需要使用 @RequestBody 类对象 的方式接收。
/**
* 新增部门
*
* @param dept 部门信息
* @return 操作结果
*/
@PostMapping("/depts") //对应前端提交时用到的请求方式
//当前端使用POST和PUT的请求体提交json格式的参数时,后端需要使用 @RequestBody 类对象 的方式接收
public Result addDept(@RequestBody Dept dept) {
deptService.addDept(dept);
return Result.success();
}Map 接收(不确定字段、动态参数)
@PostMapping("/test/map")
public String testMap(@RequestBody Map<String,Object> map){
System.out.println(map.get("username"));
return "ok";
}实体类接受
使用注意
和在query参数中使用DTO不一样的是,body参数的获取需要加@RequestBody注解,否则就是获取到的query参数。
定义一个DTO类
@Data
public class UserDTO {
private String username;
private String password;
private Integer age;
}使用DTO类:
@PostMapping("/user/add")
public Result addUser(@RequestBody UserDTO userDTO){
System.out.println(userDTO);
return Result.success();
}前端请求传递示例:
// 请求头必须带Content-Type: application/json
{
"username":"zhangsan",
"password":"123456",
"age":18
}query
方式一.适用参数较少
当前端使用(?参数)query方式提交请求参数时,@RequestParam(可以省略) 参数变量 接收参数,其中@RequestParam可以省略。
使用规则
- @RequestParam的注解可以加也可以不加,如果不加则表示可选。
- 如果加上了RequestParam注解,默认是必须传递的,可以在其中增加默认值defaultValue或者设置非必传required=false来解决
如果前后端传递的参数名称不一致的时候,可以使用@RequestParam("前端参数名称") Integer value这种格式来进行适配
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
@GetMapping("/depts")
public Result getDeptListByPage(
// 注意:如果加上了RequestParam注解,如果没加required=false表示强制必须传递的参数,不传会报错
String name,
Integer status,
// RequestParam的用法更加灵活,可以配置query参数字段映射,设置默认值和是否必须传递
// 如果加的是RequestParam注解,如果没有加required默认是true,这个时候不加默认值会报错
@RequestParam(value = "page", required = true, defaultValue = "1") Integer page,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize
) {
PageResult<Dept> deptPageResult = deptService.getDeptListByPage(name, status, page, pageSize);
return Result.success(deptPageResult);
}
}批量参数接受DTO
DTO(Data Transfer Object) : 数据传输对象,用于批量接收前端向后端传输的Query参数 , 一般以Dto结尾,放在dto包下,类似于FastAPI中的请求模型 , Query参数比较多的时候使用。
在com.cghbh.dto下创建一个DeptPageDto,用来作为查询部门数据的参数。

代码参考如下:
定义一个DTO类
package com.cghbh.dto;
import lombok.Data;
@Data
public class DeptPageDto {
private String name;
private Integer status;
// 如果没有值就使用默认设置的值
private Integer page = 1;
private Integer pageSize = 5;
}使用DTO类:
@PostMapping("/depts/add")
public Result addDept(DeptPageDto deptPageDto){
System.out.println(deptPageDto);
Result.success();
}前端请求传递示例:
// 请求头必须带Content-Type: application/json
{
"username":"zhangsan",
"password":"123456",
"age":18
}请注意
在query参数中使用DTO是不需要加@RequestBody的注解的,因为加@RequestBody的注解表示请求体body参数,不加才代表获取的是query参数。
DeptController代码
package com.cghbh.controller;
import com.cghbh.common.PageResult;
import com.cghbh.common.Result;
import com.cghbh.dto.DeptPageDto;
import com.cghbh.entity.Dept;
import com.cghbh.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
/**
* 分页查询部门列表
*
* @param deptPageDto
* @return 部门列表和总条数
*/
@GetMapping("/depts")
public Result getDeptListByPageByDto(DeptPageDto deptPageDto) {
PageResult<Dept> deptPageResult = deptService.getDeptListByPage(deptPageDto);
return Result.success(deptPageResult);
}
}DeptService代码
package com.cghbh.service;
import com.cghbh.common.PageResult;
import com.cghbh.dto.DeptPageDto;
import com.cghbh.entity.Dept;
public interface DeptService {
PageResult<Dept> getDeptListByPage(DeptPageDto deptPageDto);
}DeptServiceImpl代码
package com.cghbh.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cghbh.common.PageResult;
import com.cghbh.dto.DeptPageDto;
import com.cghbh.entity.Dept;
import com.cghbh.mapper.DeptMapper;
import com.cghbh.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class DeptServiceImpl implements DeptService {
@Autowired
private DeptMapper deptMapper;
@Override
public PageResult<Dept> getDeptListByPage(DeptPageDto deptPageDto) {
LambdaQueryWrapper<Dept> queryWrapper = Wrappers.lambdaQuery(Dept.class)
.eq(deptPageDto.getStatus() != null, Dept::getStatus, deptPageDto.getStatus())
.like(StringUtils.isNotBlank(deptPageDto.getName()), Dept::getName, deptPageDto.getName());
Page<Dept> deptPageInfo = deptMapper.selectPage(new Page<>(deptPageDto.getPage(), deptPageDto.getPageSize()), queryWrapper);
PageResult<Dept> deptPageResult = new PageResult<>();
deptPageResult.setRows(deptPageInfo.getRecords());
deptPageResult.setTotal(deptPageInfo.getTotal());
return deptPageResult;
}
}path
单个参数
当前端使用请求路径path方式提交请求参数时, 后端需要使用 @PathVariable 变量 的方式接收。
@GetMapping("/depts/{id}")
public Result getDeptInfoById(@PathVariable Integer id) {
// PathVariable会自动给我们转换为我们在后面指定的数据类型,如果转换失败则抛错
System.out.println(id);
return Result.success();
}多个参数
当前端出现/depts/1,2,3,4,5或者/depts/a,b,c,d,e这样的参数的时候,需要这样处理:
package com.cghbh.controller;
import com.cghbh.common.PageResult;
import com.cghbh.common.Result;
import com.cghbh.dto.RolePageDto;
import com.cghbh.entity.Role;
import com.cghbh.service.RoleService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/roles")
public class RoleController {
private final RoleService roleService;
@GetMapping("/demo/{ids}")
public Result getMorePath(@PathVariable("ids") List<Integer> idList) {
// path路径请求多个参数:[1, 2, 3, 4],这里是List类型
// 注意:如果都是数字类型,则可以用List<Integer>接受,否则用List<String>接受,而且必须是以英文逗号分隔开来的,不然都会报错
log.info("path路径请求多个参数:{}", idList);
return Result.success();
}
}