Skip to content

常见的请求参数的处理 ​

body ​

entity作为参数(后续开发不推荐) ​

注意

为什么不推荐直接用 Entity 接收前端 Body?

  1. 字段泄露风险 Entity 里面可能存在敏感字段:password、secret、deleteTime、version(乐观锁)、createBy、updateTime 前端如果传了这些字段,后端会直接接收,一不小心就被篡改数据库值!例如:前端偷偷传 id:999、deleted:1,直接修改别的数据或者逻辑删除

  2. 前端参数和数据库字段强耦合 数据库一改字段(改名字、新增字段),接口入参跟着变,前端也要改。 有时候接口不需要 entity 全部字段,只需要其中几个。

  3. Entity 一般有 MybatisPlus 注解(@TableName、@TableField) 虽然 jackson 反序列化不受影响,职责混乱:Entity = 映射数据库 DTO = 接收前端请求 / 返回给前端

  4. 场景:新增和修改共用一个 Entity,新增不能传 id,但 Entity 里有 id 字段,很容易出问题

当前端使用POST和PUT的请求体提交json格式的参数时,后端需要使用 @RequestBody 类对象 的方式接收。

java
/**
 * 新增部门
 *
 * @param dept 部门信息
 * @return 操作结果
 */
@PostMapping("/depts") //对应前端提交时用到的请求方式
//当前端使用POST和PUT的请求体提交json格式的参数时,后端需要使用  @RequestBody 类对象  的方式接收
public Result addDept(@RequestBody Dept dept) {
    deptService.addDept(dept);
    return Result.success();
}

Map 接收(不确定字段、动态参数) ​

java
@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类

java
@Data
public class UserDTO {
    private String username;
    private String password;
    private Integer age;
}

使用DTO类:

java
@PostMapping("/user/add")
public Result addUser(@RequestBody UserDTO userDTO){
    System.out.println(userDTO);
    return Result.success();
}

前端请求传递示例:

java
// 请求头必须带Content-Type: application/json
{
  "username":"zhangsan",
  "password":"123456",
  "age":18
}

query ​

方式一.适用参数较少 ​

当前端使用(?参数)query方式提交请求参数时,@RequestParam(可以省略) 参数变量 接收参数,其中@RequestParam可以省略。

使用规则

  1. @RequestParam的注解可以加也可以不加,如果不加则表示可选。
  2. 如果加上了RequestParam注解,默认是必须传递的,可以在其中增加默认值defaultValue或者设置非必传required=false来解决
  3. 如果前后端传递的参数名称不一致的时候,可以使用@RequestParam("前端参数名称") Integer value这种格式来进行适配
java
@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类

java
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类:

java
@PostMapping("/depts/add")
public Result addDept(DeptPageDto deptPageDto){
    System.out.println(deptPageDto);
    Result.success();
}

前端请求传递示例:

json
// 请求头必须带Content-Type: application/json
{
  "username":"zhangsan",
  "password":"123456",
  "age":18
}

请注意

在query参数中使用DTO是不需要加@RequestBody的注解的,因为加@RequestBody的注解表示请求体body参数,不加才代表获取的是query参数。

DeptController代码 ​
java
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代码 ​
java
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代码 ​
java
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 变量 的方式接收。

java
@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这样的参数的时候,需要这样处理:

java
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();
    }
}