目录
1. Mode
1. IotTypeController 基础 × 7 tips
2. 辅助添加 @Validated 无法覆盖的 参数校验
1. 预处理空指针异常 ( 校验 : 核心必填参数 not null )
3. @RequestBody 对应API 存在 feign 调用时 , 注意 : 不可缺省
1. feign API 需要加 @RequestBody , Controller 层可以忽略
2. feign API 需要加 @RequestBody , 则 请求方式需 统一为 : POST
3. Controller 省略了@RequestBody 会出现的异常 : sql 传参异常
4. 查询列表 用 GET 请求 , 入参对象以 query 路径传入
4. API 无权限调用情景 - ( 门户、首页、访客模式 )
0. New Controller - 单独统一管理
1. 详情 ( 单服务 )
2. 详情 ( 跨服务 )
3. 资源列表 ( 单服务 )
4. 资源 Page 列表 ( 跨服务 )
1. Mode
1. IotTypeController
基础 × 7 tips
private final IIotTypeService iIotTypeService;
/**
* 添加资源类型
* @param iotTypeDTO 资源类型接收入参DTO
* @return R
*/
@SysLog("添加资源类型")
@ApiOperation(value = "添加资源类型")
@ApiImplicitParams(value = {
@ApiImplicitParam(paramType = "body" , name = "iotTypeDTO" , dataType = "IotTypeDTO" , required = true , value = "资源类型对象")})
@PostMapping
public R<Boolean> saveIotType(@Validated(Save.class) @RequestBody IotTypeDTO iotTypeDTO) {
iIotTypeService.saveIotType(iotTypeDTO);
return R.ok();
}
/**
* 根据id(逻辑)删除资源类型
* @param id 资源类型id
* @return R
*/
@SysLog("根据id(逻辑)删除资源类型")
@ApiOperation(value = "根据id(逻辑)删除资源类型")
@ApiImplicitParams(@ApiImplicitParam(paramType = "query" , name = "id" , dataType = "Integer" , required = true , value = "资源类型id"))
@DeleteMapping
public R<Boolean> deleteIotType(@RequestParam("id") Integer id) {
if (null != id){
iIotTypeService.deleteIotType(id);
return R.ok();
}
return R.failed(BusinessEnum.PARAMETER_NULL);
}
/**
* 修改资源类型
* @param iotTypeDTO 资源类型接收入参DTO
* @return R
*/
@SysLog("修改资源类型")
@ApiOperation(value = "修改资源类型")
@ApiImplicitParams(value = {
@ApiImplicitParam(paramType = "body" , name = "iotTypeDTO" , dataType = "IotTypeDTO" , required = true , value = "资源类型对象")})
@PutMapping
public R<Boolean> updateIotType(@Validated(Update.class) @RequestBody IotTypeDTO iotTypeDTO) {
if(null != iotTypeDTO.getId()){
iIotTypeService.updateIotType(iotTypeDTO);
return R.ok();
}
return R.failed(BusinessEnum.PARAMETER_NULL);
}
/**
* 根据id查询资源类型详情
* @param id 资源类型id
* @return 资源类型展示对象
*/
@ApiOperation(value = "根据id查询资源类型详情")
@ApiImplicitParams(@ApiImplicitParam(paramType = "query" , name = "id" , dataType = "Integer" , required = true , value = "资源类型id"))
@GetMapping("/detail")
public R<IotTypeVO> queryIotType(@RequestParam("id") Integer id) {
if (null != id){
return R.ok(iIotTypeService.queryIotType(id));
}
return R.failed(BusinessEnum.PARAMETER_NULL);
}
/**
* 无参查询资源类型List
* @return 资源类型展示对象集合IotTypeVOList
*/
@ApiOperation(value = "无参查询资源类型List")
@GetMapping("/list")
public R<List<IotTypeVO>> queryIotTypeList() {
return R.ok(iIotTypeService.queryIotTypeList());
}
/**
* 条件询资源类型List
* @param iotTypeDTO 资源类型接收入参DTO
* @return 资源类型展示对象集合IotTypeVOList
*/
@ApiOperation(value = "条件询资源类型List")
@ApiImplicitParams(value = {
@ApiImplicitParam(paramType = "body" , name = "iotTypeDTO" , dataType = "IotTypeDTO" , required = false , value = "资源类型对象")})
// @GetMapping("/list/conditions") - 需要考虑空对象的情况 , 经过测试 , postman可以在query路径传空获取all数据 ,
// 但前端是否可以query传空获取数据 , 情况未知 , 待校验。(降级处理 以Post请求获取查询数据 , entity前添加 @Requestbody 进行参数转换)
@GetMapping("/list/conditions")
public R<List<IotTypeVO>> queryListByConditions(IotTypeDTO iotTypeDTO) {
return R.ok(iIotTypeService.queryListByConditions(iotTypeDTO));
}
/**
* 条件查询资源类型Page
* @param page 分页参数
* @param iotTypeDTO 资源类型接收入参DTO
* @return 资源类型展示对象集合IotTypeVOList
*/
@ApiOperation(value = "条件查询资源类型Page")
@ApiImplicitParams(value = {
@ApiImplicitParam(paramType = "body" , name = "page" , dataType = "Page" , required = true , value = "分页条件") ,
@ApiImplicitParam(paramType = "body" , name = "iotTypeDTO" , dataType = "IotTypeDTO" , required = false , value = "资源类型对象")})
@GetMapping("/page/conditions")
public R<IPage<IotTypeVO>> queryPageByConditions(Page page , IotTypeDTO iotTypeDTO) {
return R.ok(iIotTypeService.queryPageByConditions(page , iotTypeDTO));
}
2. 辅助添加 @Validated
无法覆盖的 参数校验
1. 预处理空指针异常 ( 校验 : 核心必填参数 not null )
/**
* 根据id查询公寓详情(跨服务)
*
* @param id 公寓id
* @return 公寓展示对象IotHouseVO
*/
@ApiOperation(value = "根据id查询公寓详情(跨服务)")
@GetMapping("/detail")
@ApiImplicitParams(@ApiImplicitParam(paramType = "query", name = "id", dataType = "Integer", required = true, value = "公寓id"))
public R<IotHouseVO> queryIotHouseDetail(@RequestParam("id") Integer id) {
if (null != id) {
// 每请求一次,key = SCORE_RANK,value = id 对应的 score 计数 + 1
// 若 value = id 不存在,则进行对应的 score 初始化 = 1
redisTemplate.opsForZSet().incrementScore(SCORE_RANK, id.toString(), 1);
return R.ok(iiotHouseService.queryIotHouseDetail(id));
}
return R.failed(BusinessEnum.PARAMETER_NULL);
}
3. @RequestBody 对应API 存在 feign 调用时 , 注意 : 不可缺省
1. feign API 需要加 @RequestBody , Controller 层可以忽略
2. feign API 需要加 @RequestBody , 则 请求方式需 统一为 : POST
/**
* 条件查询公寓列表
*
* @param iotHouseDTO 公寓接收入参DTO
* @return 公寓展示对象集合IotHouseVOList
*/
@ApiOperation(value = "条件查询公寓列表")
@ApiImplicitParams(value = {
@ApiImplicitParam(paramType = "body", name = "iotHouseDTO", dataType = "IotHouseDTO", required = true, value = "公寓对象")})
@PostMapping("/lists/conditions")
public R<List<IotHouseVO>> queryListByConditions(@RequestBody IotHouseDTO iotHouseDTO) {
return R.ok(iiotHouseService.queryListByConditions(iotHouseDTO));
}
原本,可用 GetMapping + iotHouseDTO 对象
但由于,需要提供 对应的 feign AP
/**
* @Author: 猫猫聚会Ing
* @Date: 2021/7/26 15:25
* @Description 公寓feign接口
*/
@FeignClient(contextId = "remoteIotHouseService", value = ServiceNameConstants.IOT_APARTMENT_BIZ)
public interface RemoteIotHouseService {
/**
* 条件查询公寓列表
* @param iotHouseDTO 公寓接收入参DTO
* @return 公寓展示对象集合IotHouseVOList
*/
@PostMapping("/house/lists/conditions")
R<List<IotHouseVO>> queryListByConditions(@RequestBody IotHouseDTO iotHouseDTO);
}
3. Controller 省略了@RequestBody 会出现的异常 : sql 传参异常
情景 :
删除资产结构时 , 无论对应 id 为多少 , feign API 查询返回结果都是资源管理所有数据
// 添加资源模块应用校验
IotResourcesDTO iotResourcesDTO = new IotResourcesDTO();
iotResourcesDTO.setStructureId(id);
R<List<IotResourcesVO>> listR = remoteResourcesService.selectListByCondition(iotResourcesDTO);
if(0 == listR.getCode() && !listR.getData().isEmpty()){
throw new IotAssetStructureException("当前资产结构节点已被资源管理占用 , 请核实后操作");
}
this.removeById(id);
return Boolean.TRUE;
测试得出 :
iotResourcesDTO 参数传递出现异常情况 , 实际上接受失败
解决 :
在 Controller 层对应方法入参上添加 @RequestBody 注解
/**
* 条件查询资源信息
* @param iotResourcesDTO 资源信息传输对象
* @return List<IotResourcesVO>
*/
@ApiOperation(value = "条件查询资源信息")
@ApiImplicitParams(value = {
@ApiImplicitParam(paramType = "body" , name = "iotResourcesDTO" , dataType = "IotResourcesDTO" , required = false , value = "条件查询对象")})
@PostMapping("/list/conditions")
public R<List<IotResourcesVO>> selectListByCondition(@RequestBody IotResourcesDTO iotResourcesDTO) {
return R.ok(iIotResourcesService.selectListByCondition(iotResourcesDTO));
}