【实际开发07】- XxxxController 批量处理 × 5 -【model】

news2024/11/28 10:44:31

目录

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

 

 


4. 查询列表 用 GET 请求 , 入参对象以 query 路径传入


4. API 无权限调用情景 - ( 门户、首页、访客模式 )


0. New Controller - 单独统一管理


1. 详情 ( 单服务 )


2. 详情 ( 跨服务 )


3. 资源列表 ( 单服务 )


4. 资源 Page 列表 ( 跨服务 )

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/166553.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

手工测试 | 黑盒测试方法论—边界值

本文节选自霍格沃兹测试学院内部教材 边界值分析法是一种很实用的黑盒测试用例方法&#xff0c;它具有很强的发现故障的能力。边界值分析法也是作为对等价类划分法的补充&#xff0c;测试用例来自等价类的边界。 这个方法其实是在测试实践当中发现&#xff0c;Bug 往往出现在定…

OpenCV4.6 VS 4.7 QRCode解码功能效果对比

导 读 本文主要对OpenCV4.7.0和4.6.0中QRCode检测/解码功能做简单的测试对比&#xff0c;供大家参考。 背景介绍 最近OpenCV更新到了4.7.0版本&#xff0c;在ChangeLog算法部分除了新增Stackblur滤波算法(详细介绍见下面链接)&#xff0c;还有对QRCode检测和解码的改进。 吊打…

实现通讯录(C语言)

功能实现 实现步骤&#xff1a; 创建通讯录 初始化通讯录 打印菜单 实现选择功能 实现添加功能 实现删除功能 实现查找功能 实现修改功能 实现清空功能 实现排序功能 实现查询所有联系人信息功能 通讯录总代码 创建通讯录 1、创建成员信息结构体 我们用结构体来封装一个联系人…

【系列04】数组 多维数组 冒泡排序 稀疏数组[有目录]

数组声明和创建 变量类型 变量名称 变量的值 声明数组 int []nums;//定义//上面是首选 /*也可以 int nums2[];*/下面这种写法是为了迎合c与c用户的喜爱,更推荐用上面的定义 方式 创建数组 numsnew int[10];定义数组计算数组的和 package com.SunAo.array; //变量类型 变量名称…

TypeScript 数据模型层编程的最佳实践

虽然 TypeScript 主要用于客户端&#xff0c;而数据模型的设计主要是服务端来做的。 但是要写出优雅的代码&#xff0c;也还是有不少讲究的。 让我们从一个简单的我的文章列表 api 返回的数据开始&#xff0c;返回的文章列表的信息如下&#xff1a; {"id": 2018,&qu…

原生PHP及thinkphp6接入阿里云短信

申请accesskey获取到Accesskey ID和Accesskey Secret保存下来&#xff0c;一会要用到添加测试手机号&#xff0c;在接口测试能否正常发送下载阿里云短信sdk&#xff0c;使用composer下载&#xff0c;没有安装请先安装安装可以安装到任意文件夹下&#xff0c;后面代码写好后&…

TDSQL的安装教程(低配体验)

一、了解TDSQL tdsql腾讯云文档 TDSQL-C MySQL 版&#xff08;TDSQL-C for MySQL&#xff09;是腾讯云自研的新一代云原生关系型数据库。融合了传统数据库、云计算与新硬件技术的优势&#xff0c;为用户提供具备极致弹性、高性能、海量存储、安全可靠的数据库服务。TDSQL-C My…

AtCoder Beginner Contest 285解题报告

A - Edge Checker 2 Problem Statement Determine if there is a segment that directly connects the points numbered a and b in the figure below. Constraints 1≤a<b≤15a and b are integers.Input The input is given from Standard Input in the following for…

用SpectorJS调试WebGL应用

随着使用 WebGL 构建的体验不断涌现&#xff0c;以及 WebVR/AR 领域的所有改进&#xff0c;拥有高效的调试工具变得至关重要。 无论你是刚刚起步还是已经是使用 WebGL 开发 3D 应用程序的经验丰富的开发人员&#xff0c;都可能知道工具对于生产力的重要性。 在寻找此类工具时&…

【开发环境】JRE 裁剪 ① ( 裁剪 bin 目录下的 dll 动态库文件 )

文章目录一、JRE 裁剪二、裁剪 bin 目录下的 dll 动态库文件参考博客 : 精简jre1.8精简jre步骤裁剪JRE(嵌入式设备的java环境移植) 资源下载地址 : https://download.csdn.net/download/han1202012/87388400 一、JRE 裁剪 在 【IntelliJ IDEA】使用 exe4j 生成 jre jar 可执…

华为MPLS跨域A、B方案实验配置

目录 MPLS域内配置 MPLS-AS100域内配置 MPLS-AS200域内配置 域间方式A配置 ASBR4和ASBR5配置实例 ASBR之间建立基于实例的EBGP邻居关系 域间方式B配置 ASBR相连接口开启MPLS ASBR之间建立MP-BGP的EBGP邻居 配置取消RT值检测 配置传递路由时更改下一跳为自身 MPLS域内…

程序员必知必会 QPS TPS、URI URL、PV UV GMV

一、QPS和 TPS QPS&#xff1a;Queries Per Second&#xff0c;意思是“每秒查询数”&#xff0c;是一台服务器每秒能够响应的查询次数&#xff0c;是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准。 即最大吞吐能力。 TPS&#xff1a;TransactionsPerSecond&…

springboot整合log4j2

导入依赖 <dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version> </dependency><!--log4j2--> <dependency><groupId>org.apache.logging.log4j</groupId>&…

Spring Boot(五十三):SpringBoot Actuator之实现

1 场景介绍 对于一个大型的几十个、几百个微服务构成的微服务架构系统&#xff0c;在线上时通常会遇到下面一些问题&#xff0c;比如&#xff1a; 1. 如何知道哪些服务除了问题&#xff0c;如何快速定位&#xff1f; (健康状况&#xff09; 2. 如何统一监控各个微服务的性能指标…

JAVA会员营销系统源码+数据库,实体店铺会员管理和营销系统源码,采用SpringBoot + Mysql+Mybatis

会员营销系统介绍 介绍 fuint会员营销系统是一套开源的实体店铺会员管理和营销系统。系统基于前后端分离的架构&#xff0c;后端采用Java SpringBoot Mysql&#xff0c;前端基于当前流行的Uniapp&#xff0c;Element UI&#xff0c;支持小程序、h5。主要功能包含电子优惠券、…

冰蝎V4.0流量分析到攻防检测

0x01 前言 最近在改写 yso&#xff0c;觉得自己基础太差了&#xff0c;想先阅读一下 sqlmap、冰蝎以及一些其他工具的开发思路。文章可能写的不够严谨&#xff0c;有不对的地方还请师傅们多多指出。 0x02 环境搭建 这里我看的是 MountCloud 师傅所二开的冰蝎项目&#xff0c…

【关于Linux中----进程间通信方式之system V共享内存】

文章目录一、共享内存示意图二、学习共享内存前的准备工作三、共享内存函数3.1创建共享内存&#xff1a;3.2控制共享内存&#xff1a;3.3挂接和去挂接&#xff1a;一、共享内存示意图 上一篇文章中讲述的是管道的通信方式&#xff0c;而这里要讲的是操作系统层面专门为进程间通…

编译原理-链接实例分析

gcc-arm-none-eabi 工具链功能1.arm-none-eabi-gcc &#xff1a;c语言编译器&#xff0c;可以将.c文件编译为.o的执行文件2.arm-none-eabi-g &#xff1a;c编译器&#xff0c;可以将.cpp文件编译成.o的执行文件3.arm-none-eabi-ld : 链接器&#xff0c;链接所有的.o文件生成可执…

CDH6.3生产环境中禁用Kerberos

在集群启用Kerberos后&#xff0c;会对现有环境的部分代码做改造&#xff0c;有些人觉得使用起来不方便&#xff0c;想取消Kerberos。本篇文章主要介绍如何禁用CDH集群的Kerberos及禁用后对各组件服务的测试。修改了网上相关文档的一些缺陷&#xff0c;在生产环境中实际使用过通…

GIT ---- GitHub配置SSH Key的完整步骤

1. 配置 SSH Key 由于提交代码每次输入用户名和密码&#xff0c;很繁琐&#xff0c;所以直接配置 SSH Key&#xff0c;直接自动验证&#xff0c;减少提交代码的操作步骤。 2. 查看配置命令 git config --list 查看当前Git环境所有配置&#xff0c;还可以配置一些命令别名之类…