学成在线第二天-查询课程、查询课程分类、新增课程接口实现以及跨域的处理思路和全局异常处理的使用以及面试题
目录
一、接口的实现
二、跨域的处理思路
三、全局异常处理
四、面试题
五、总结
一、接口的实现
1. 查询课程接口
思路:
典型的分页查询 + 按需查询 + 模糊查询的查询
controller:
@ApiOperation(value = "课程列表", notes = "课程列表")@PostMapping("/list")public PageResult<CourseBase> courses(PageParams pageParams, @RequestBody CourseBaseInfoDto courseBaseInfoDto) {PageResult<CourseBase> pageResult = courseBaseService.courses(pageParams, courseBaseInfoDto);return pageResult;}
service接口及其实现;
public interface CourseBaseService extends IService<CourseBase> {PageResult courses(PageParams pageParams, CourseBaseInfoDto courseBaseInfoDto);
}
@Service
public class CourseBaseServiceImpl extends ServiceImpl<CourseBaseMapper, CourseBase>implements CourseBaseService{@Autowiredprivate CourseMarketService courseMarketService;@Overridepublic PageResult<CourseBase> courses(PageParams pageParams, CourseBaseInfoDto courseBaseInfoDto) {Page<CourseBase> page = new Page<>(pageParams.getPageNo(), pageParams.getPageSize());LambdaQueryWrapper<CourseBase> wrapper = new LambdaQueryWrapper<>();wrapper.like(StringUtils.hasText(courseBaseInfoDto.getCourseName()),CourseBase::getName,courseBaseInfoDto.getCourseName());wrapper.eq(StringUtils.hasText(courseBaseInfoDto.getAuditStatus()),CourseBase::getAuditStatus,courseBaseInfoDto.getAuditStatus());wrapper.eq(StringUtils.hasText(courseBaseInfoDto.getPublishStatus()),CourseBase::getStatus,courseBaseInfoDto.getPublishStatus());page(page,wrapper);List<CourseBase> records = page.getRecords();PageResult<CourseBase> pageResult = PageResult.ok(records, page.getTotal());return pageResult;}
}
2. 查询课程分类接口
典型的对树形数据结构的查询
通过数据库中的parentId字段,就能实现
@Service
public class CourseCategoryServiceImpl extends ServiceImpl<CourseCategoryMapper, CourseCategory>implements CourseCategoryService{/*** 获取分类树* @return*/@Overridepublic List<CourseCategoryNode> courseCategoryTreeNodes() {//1. 先查出所有节点List<CourseCategory> categories = list();List<CourseCategoryNode> courseCategoryNodes = BeanUtil.copyToList(categories, CourseCategoryNode.class);List<CourseCategoryNode> collect = Collections.EMPTY_LIST;if(courseCategoryNodes!=null && courseCategoryNodes.size()>0){collect = courseCategoryNodes.stream().filter(category-> category.getParentid().equals("1")).map(categoryNode -> {List<CourseCategoryNode> childrenTreeNodes = children(categoryNode.getId(), courseCategoryNodes);categoryNode.setChildrenTreeNodes(childrenTreeNodes);return categoryNode;}).sorted((category1, category2) -> category1.getOrderby() == null? 0 : category1.getOrderby() - (category2.getOrderby() == null? 0 : category2.getOrderby())).collect(Collectors.toList());}return collect;}private List<CourseCategoryNode> children(String id, List<CourseCategoryNode> categories) {List<CourseCategoryNode> collect = Collections.EMPTY_LIST;//注意判空if (categories != null && categories.size() > 0) {//1. 遍历所有节点 找到其节点的一级子节点collect = categories.stream().filter(category -> category.getParentid().equals(id)).map(category -> {//2. 再对一级子节点进行递归查找子节点category.setChildrenTreeNodes(children(category.getId(), categories));return category;}).sorted((category1, category2) -> category1.getOrderby() == null? 0 : category1.getOrderby() - (category2.getOrderby() == null? 0 : category2.getOrderby())).collect(Collectors.toList());}return collect;}
}
注意:
1. courseCategoryNodes.stream().filter(category-> category.getParentid().equals("1"))
这个是确保第一级就是 真正的第一级同级 而不会出现 第二级也作为父节点
2. 可以使用map 看似这里其实只是一个简单的set而并没有真正的将其对象进行转换,所以可以直接使用foreach,但是因为这里还有一个sort的后续对流的操作,所以可以使用map,使用map就能连续的对流进行处理
3. 注意避免空指针
要有这种意识,一旦对数组使用stream来操作,数组一定不能为null
还有就是在流处理中,通常可以获取到对象,而去调用对象的get方法,此时就需要主要判空
3. 新增课程信息接口
典型的多表新增 并且必须新增完上一个才能新增下一个也就是关联新增
还有就是新增和修改是一个接口,需要判断是新增还是修改
可以通过标识位判断,另外还可以查看数据库中数据是否存在的方法...老师写的有点问题
这里下面的营销信息是基于上面的基本信息,所以说下面一定是新增
正确的做法应该是再添加一个专门的修改方法
这里建议是不要将修改和添加合并
二、跨域的处理思路
1. 前端使用JSONP的方式
2. 使用过滤器 或者是拦截器 适用于单体服务
拦截器:
@Configuration
public class WebConfig implements WebMvcConfigurer {/*** 配置跨域** @param registry*/@Overridepublic void addCorsMappings(CorsRegistry registry) {// 设置允许跨域的路径registry.addMapping("/**")// 设置允许跨域请求的域名.allowedOriginPatterns("*")// 是否允许cookie.allowCredentials(true)// 设置允许的请求方式.allowedMethods("GET", "POST", "DELETE", "PUT")// 设置允许的header属性.allowedHeaders("*")// 跨域允许时间.maxAge(3600);// 设置可被访问的响应头//.exposedHeaders("jieiwi");}
}
过滤器:
@Configurationpublic class GlobalCorsConfig {/*** 允许跨域调用的过滤器*/@Beanpublic CorsFilter corsFilter() {CorsConfiguration config = new CorsConfiguration();//允许白名单域名进行跨域调用config.addAllowedOrigin("*");//允许跨越发送cookieconfig.setAllowCredentials(true);//放行全部原始头信息config.addAllowedHeader("*");//允许所有请求方法跨域调用config.addAllowedMethod("*");UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();source.registerCorsConfiguration("/**", config);return new CorsFilter(source);}}
还可以添加@CrossOrigin的方式
3. 在网关中配置
gateway:globalcors:cors-configurations:'[/**]': # 匹配所有请求allowedOrigins: "*" #跨域处理 允许所有的域allowedMethods: # 支持的方法- GET- POST- PUT- DELETE
4. 使用nginx反向代理
由于浏览器直接访问对应的服务会跨域,那么可以不让浏览器直接访问服务,而是先将请求发给nginx,再由nigix代理给对应的服务
其实就是将浏览器环境变成了ngixn环境
因为在nginx中配置前端静态资源是很方便的,那么就可以利用ngixn,直接在浏览器中访问到nginx中的静态资源,这里是不会跨域的,这是由nginx的特点所决定的,nginx本来就可以实现动静分离 然后再在nginx中进行反向代理 将请求代理给服务集群
参考:http://t.csdnimg.cn/i2nS9
三、全局异常处理
@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(value = PriceException.class)public RestErrorResponse handlePriceException(PriceException e) {return new RestErrorResponse(e.getMessage());}@ExceptionHandler(value = MethodArgumentNotValidException.class)public RestErrorResponse handleArgsException(MethodArgumentNotValidException e) {List<String> collect = e.getBindingResult().getFieldErrors().stream().map(fieldError -> {return fieldError.getField()+fieldError.getDefaultMessage();}).collect(Collectors.toList());return new RestErrorResponse(StrUtil.join(",", collect));}@ExceptionHandler(value = Exception.class)public RestErrorResponse handException(){return new RestErrorResponse(CommonError.UNKOWN_ERROR.getErrMessage());}}
这个最终肯定是要返回前端以标准的响应体返回的,这样前端才能拿到异常信息,进行显示
至于这个返回给前端的异常信息到底是怎样的,可以直接 在抛出异常的时候指定好错误,然后在全局异常处理中直接调用异常对象的方法获取到异常信息
return new RestErrorResponse(e.getMessage());
也可以不使用那里的,而是再全局异常中再去自己指定。另外这里的异常信息推荐使用将其封装成枚举 比如下面这样:
return new RestErrorResponse(CommonError.UNKOWN_ERROR.getErrMessage());
反正也就是响应类和枚举类之间的玩法
四、面试题
1. mybais中的分页插件的原理
其实就是将分页参数放到ThreadLocal中,然后根据不同的数据库类型添加对应的分页语句重写sql,例如将select * from table where a=xx 将其重写为 select count(*) from table where a = xx求出总数,然后还有一条select * from table where a = xx limit , 获取到数据
2. 异常处理
使用全局异常处理机制进行处理
@RestControllerAdvice注解和@ExceptionHandle可以处理自定义异常和系统异常 返回自己的异常信息
五、总结
还是几个常见接口的实现 现在来说应该说不能有难度了
分页查询、树形查询....新增和修改....
还是跨域和异常处理 但是学到了更多的处理跨域问题的解决办法
再就是知道mybatis分页插件的原理
相关文章:
学成在线第二天-查询课程、查询课程分类、新增课程接口实现以及跨域的处理思路和全局异常处理的使用以及面试题
目录 一、接口的实现 二、跨域的处理思路 三、全局异常处理 四、面试题 五、总结 一、接口的实现 1. 查询课程接口 思路: 典型的分页查询 按需查询 模糊查询的查询 controller: ApiOperation(value "课程列表", notes "课程…...
【OpenCV概念】 11— 对象检测
一、说明 这都是关于物体识别的。物体识别是指通过计算机视觉技术,自动识别图像或视频中的物体及其属性和特征,是人工智能领域的一个分支。物体识别可应用于多个领域,包括工业自动化、智能家居、医疗、安防等。请随时阅读这篇文章:…...
TensorRT学习笔记--常用卷积、激活、池化和FC层算子API
目录 1--Tensor算子API 1-1--卷积算子 1-2--激活算子 1-3--池化算子 1-4--FC层算子 2--代码实例 3--编译运行 1--Tensor算子API TensorRT提供了卷积层、激活函数和池化层三种最常用算子的API: // 创建一个空的网络 nvinfer1::INetworkDefinition* network …...
【Edabit 算法 ★☆☆☆☆☆】 Less Than 100?
【Edabit 算法 ★☆☆☆☆☆】 Less Than 100? language_fundamentals math validation Instructions Given two numbers, return true if the sum of both numbers is less than 100. Otherwise return false. Examples lessThan100(22, 15) // true // 22 15 37lessTha…...
C++中的智能指针:更安全、更便利的内存管理
在C++编程中,动态内存管理一直是一个重要且具有挑战性的任务。传统的C++中,程序员需要手动分配和释放内存,这往往会导致内存泄漏和悬挂指针等严重问题。为了解决这些问题,C++11引入了智能指针(Smart Pointers)这一概念,它们是一种高级的内存管理工具,可以自动管理内存的…...
google登录k8s dashboard ui显示“您的连接不是私密连接”问题解决梳理
1.问题描述 OS Version:CentOS Linux release 7.9.2009 (Core) K8S Version:Kubernetes v1.20.4 k8s dashboard ui安装完毕后,通过google浏览器登录返现https网页,发现非官方的https网页无法打开 网址:https://192.168.10.236:31001 2.原…...
MIPS指令集摘要
目录 MIPS指令R I J三种格式 MIPS五种寻址方式 立即数寻址 寄存器寻址 基址寻址 PC相对寻址 伪直接寻址 WinMIPS64汇编指令 助记 从内存中加载数据 lb lbu lh lhu lw lwu ld l.d lui 存储数据到内存 sb sh sw sd s.d 算术运算 daddi daddui dadd…...
数据可视化素材分享 | 数十图表、无数模板
很多人在后台求分享报表、源代码,其实何必这么麻烦,在奥威BI数据可视化平台上点击即可获得大量的可视化素材,如数十种可视化图表,适用于不同分析场景;又如大量不同主题的BI数据可视化报表模板,套用后替换数…...
Hadoop3教程(三十二):(生产调优篇)NameNode故障恢复与集群的安全模式
文章目录 (159)NameNode故障处理(160)集群安全模式&磁盘修复集群安全模式磁盘修复等待安全模式 参考文献 (159)NameNode故障处理 如果NameNode进程挂了并且存储的数据也丢失了,如何恢复Nam…...
uniapp下载附件保存到手机(文件、图片)ios兼容
downloadFile(file),其中file为下载的文件地址uni.downloadFile图片使用uni.saveImageToPhotosAlbum【安卓、ios都合适】文件使用uni.openDocument【安卓图片也可以用这个,ios会失败】 // 下载文件 export function downloadFile(file) {let acceptArr …...
【Edabit 算法 ★☆☆☆☆☆】 Basketball Points
【Edabit 算法 ★☆☆☆☆☆】 Basketball Points language_fundamentals math numbers Instructions You are counting points for a basketball game, given the amount of 2-pointers scored and 3-pointers scored, find the final points for the team and return that …...
Web攻防04_MySQL注入_盲注
文章目录 MYSQL-SQL操作-增删改查盲注概念盲注分类盲注语句参考&更多盲注语句/函数 注入条件-数据回显&错误处理PHP开发项目-注入相关条件:基于延时:基于布尔:基于报错: CMS案例-插入报错&删除延时-PHP&MYSQL1、x…...
Flask自定义装饰和g的使用
1. 在commons.py文件中新增一个装饰器类: 注:一定要加入wraps进行装饰否则,装饰器在给多个函数进行装饰时会报错 from functools import wraps from flask import session, current_app, g# 定义登陆装饰器,封装用户的登陆数据 def user_log…...
【汇编】汇编语言基础知识(学习笔记)
一、汇编语言概述 汇编语言是直接在硬件之上工作的编程语言,首先要了解硬件奈统的结构,才能有效的应用汇编语言对其编程。 二、汇编语言的产生 机器语言:机器语言是机器指令的集合 汇编语言的主体是汇编指令 汇编指令和机器指令的差别在…...
前端 | FormData 用法详解
前端 | FormData 用法详解 介绍 FormData 是 Ajax2.0 对象用以将数据编译成键值对,以便于 XMLHttpRequest 来发送数据。XMLHttpRequest Level 2 提供的一个接口对象,可以使用该对象来模拟和处理表单并方便的进行文件上传操作 如果表单属性设为 mu…...
linux常见命令-文件目录类
9.4 文件目录类 (1)pwd 指令:显示当前工作目录的绝对路径 (2)Is指令:查看当前目录的所有内容信息 基本语法: ls [选项,可选多个] [目录或是文件] 常用选项:-a:显示当前目录所有的文件和目录,包括隐藏的…...
2023 10月8日 至 10 月16日学习总结
1.做的题目 [RootersCTF2019]I_<3_Flask_双层小牛堡的博客-CSDN博客 [NCTF2019]SQLi regexp 盲注-CSDN博客 [网鼎杯 2018]Comment git泄露 / 恢复 二次注入 .DS_Store bash_history文件查看-CSDN博客 PHP LFI 利用临时文件Getshell_双层小牛堡的博客-CSDN博客 …...
【Java 进阶篇】深入了解 Bootstrap 表格和菜单
表格和菜单是网页设计中的重要组成部分,它们用于展示数据、导航和用户交互。Bootstrap 是一个强大的前端框架,提供了丰富的表格样式和菜单组件,使开发者能够轻松创建功能丰富的网页。在本文中,我们将深入探讨 Bootstrap 中表格和菜…...
java的for循环中遇到异常抛出后继续循环执行
java的for循环中遇到异常抛出后继续循环执行 Test public void loopTryCatchTest() throws Exception {Map<String, Object> a new HashMap();a.put("a", "1");a.put("b", null);a.put("c", "3");for (Map.Entry<…...
【Javascript】构造函数之new的作用
目录 new的作用 把对象返回了回来 无new 有new 把构造函数的this指向了要返回的对象 无new编辑 有new new的执行流程 new的作用 创建了新空对象将构造函数的作用域赋值给新对象(this指向新对象)执行构造函数代码 (为这个新对象添加属性)返回新对…...
兔抗PHLPPL抗体亲和纯化,IP/WB双平台验证,精准检测Akt调控因子
一、产品概述由艾美捷Bethyl Laboratories推出的兔抗PHLPPL抗体亲和纯化抗体,货号:A300-661A是一款以兔为宿主来源、针对人PHLPPL蛋白的多克隆抗体。该抗体采用抗原亲和纯化工艺制备,以完整IgG形式提供,浓度为200 g/ml,…...
别再重装环境了!手把手教你迁移Python虚拟环境(解决Fatal error in launcher报错)
Python虚拟环境迁移实战:彻底解决路径依赖与Fatal error报错 每次接手同事的Python项目或从GitHub克隆代码时,最让人头疼的莫过于那个精心配置却无法正常激活的虚拟环境。特别是当看到Fatal error in launcher: Unable to create process using...这样的…...
PlatformIO隐藏技巧:用Python脚本自动生成HEX文件(附STM32实测)
PlatformIO高阶技巧:Python脚本自动化生成HEX文件的深度实践 如果你已经习惯了Keil中一键生成HEX文件的便捷,却在PlatformIO中苦苦寻找这个功能,那么这篇文章正是为你准备的。PlatformIO作为现代嵌入式开发的利器,虽然默认不直接生…...
Windows服务器IIS部署PHP:FastCGI常见报错排查与修复指南
1. 环境准备与基础配置检查 在Windows Server上部署PHP应用时,IIS与FastCGI的配合就像两个初次见面的陌生人,需要正确的"介绍人"才能顺利沟通。我遇到过太多因为基础环境缺失导致的报错,往往一个简单的复选框就能解决问题。 首先打…...
WebUploader能否支持航空航天领域的目录结构上传?
作为一名前端开发工程师,我近期接手了公司一个有些年头的旧项目改造工作。这次改造的核心需求,是要给这个旧项目增添大文件上传功能,尤其得支持 10G 左右文件的上传,并且还要具备断点续传的能力。 在众多解决方案中,我…...
Docker 27跨架构镜像转换失效?3大隐性陷阱(QEMU崩溃、binfmt注册异常、manifest list校验失败)全解析(生产环境血泪复盘)
第一章:Docker 27跨架构镜像转换失效的典型现象与定位全景当使用 Docker 27(特别是 27.0.0 版本)执行 docker buildx build --platform 构建多架构镜像时,开发者常遭遇构建成功但运行时崩溃、QEMU 模拟失败或 exec format error 等…...
如何利用AFL++进行高效模糊测试:发现软件漏洞的终极指南
如何利用AFL进行高效模糊测试:发现软件漏洞的终极指南 【免费下载链接】AFLplusplus The fuzzer afl is afl with community patches, qemu 5.1 upgrade, collision-free coverage, enhanced laf-intel & redqueen, AFLfast power schedules, MOpt mutators, un…...
如何彻底清理macOS应用残留?Pearcleaner给你答案
如何彻底清理macOS应用残留?Pearcleaner给你答案 【免费下载链接】Pearcleaner A free, source-available and fair-code licensed mac app cleaner 项目地址: https://gitcode.com/gh_mirrors/pe/Pearcleaner 你是否曾经遇到过这样的困扰:删除了…...
Overleaf实战:手把手教你用LaTeX画出教科书级别的分块矩阵与范数
Overleaf实战:教科书级分块矩阵与范数绘制指南 如果你曾在学术论文或技术文档中遇到过需要展示复杂矩阵结构的情况,一定体会过排版带来的挫败感。传统文字处理软件对数学公式的支持总是差强人意,而LaTeX作为科研排版的事实标准,却…...
Blender贝塞尔曲线终极指南:从零到精通的完整工作流
Blender贝塞尔曲线终极指南:从零到精通的完整工作流 【免费下载链接】blenderbezierutils Blender Add-on with Bezier Utility Ops 项目地址: https://gitcode.com/gh_mirrors/bl/blenderbezierutils 如果你曾经在Blender中尝试绘制贝塞尔曲线,可…...
