苍穹外卖随记(一)

news2024/9/17 7:32:29

黑马苍穹外卖逻辑和细节的问题和解决

1.后端查询到员工的日期信息,将信息进行json化传给前端时发生:前端收到的是不标准的日期json串。

解决:1.注解进行json格式化(@JsonFormat)2. 在spring MVC中,通过消息转换器(重写configureMessageConverters方法),统一进行日期的标准json化

2.关于在设计接口时,返回值的Result是否带有泛型,主要取决于Result的data属性。data是我们给前端传输的数据,我们当设计到查询业务时,应该设定泛型

3.//TODO:直接在接口测试传参数的时候发现,我们在进行员工信息修改时输入的信息并没有合法化,但是也能保存入数据库。因此会发现,当再次进行信息修改时,原本的信息会被判定为不合法

4.如何实现自动填充公共字段(逻辑思路:需要干什么?;怎么写?【熟悉反射等机制】)

解决:解决代码重用问题,我们会想到aop,也就是切面思维。那么其底层的实现逻辑其实就是使用拦截器,去拦截需要对公共字段进行赋值的方法,然后对他进行赋值。那么有个问题是:如何让拦截器知道,我们需要拦截的方法是哪些呢?其实就是给一个标志。基于这个思路:我们的解决办法其实也就是 自定义注解AutoFill和自定义切面AutoFillAspect。最后在Mapper的方法上加入AutoFill注解

自定义注解AutoFill,用于标识出需要进行公共字段自动填充的方法

自定义切面类AutoFillAspect,统一拦截加入了AutoFill注解的方法,通过反射为公共字段赋值

技术点:自定义注解、自定义切面、定义切入点、定义通知方法

5.借助 阿里云oss存储 上传文件

使用MultipartFile接口的参数,实现http文件上传

MultipartFile 是 Spring 框架中用于处理 HTTP 文件上传的一个接口。它定义了处理上传文件所需的基本操作,比如获取文件名、文件大小、文件类型以及最重要的,获取文件的字节流来读取文件内容。

6.Endpoint 通常包含地域信息和阿里云的服务标识,如 oss-cn-beijing.aliyuncs.com 中的 oss 表示对象存储服务,cn-beijing 表示中国北京地域。aliyuncs.com 是阿里云的顶级域名。

7.@ConditionalOnMissingBean 是一个 Spring 框架的注解,它用来确保当没有其他相同类型的 bean 存在于 Spring 容器中时,才创建并注册一个 bean。简单来说,它的作用就是:

  1. 如果系统中没有这个类型的 bean,就创建一个。

  2. 如果已经有了,就不创建了,避免重复。

这个注解通常用在自动配置类中,以提供一个默认的 bean 实现,让开发者可以根据自己的需要替换掉这个默认实现。

8.

//根据id修改菜品信息和对应的口味信息
    @Override
    public void updateWithFlavor(DishDTO dishDTO) {
        //菜品基本信息直接修改:菜品基本信息 直接dish类型,不需要dto
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishDTO,dish);
        dishMapper.update(dish);
        //菜品口味由于多种可能:未改、追加、全部修改【不是简单的变量的数据修改】
        //删除原来的口味数据
        dishFlavorMapper.deleteByDishId(dishDTO.getId());
        //再用传来的参数重新新增口味
        List<DishFlavor> flavors = dishDTO.getFlavors();
        if(flavors != null && !flavors.isEmpty()){
            //口味信息也可能是新增的口味,
            flavors.forEach(dishFlavor -> {
                dishFlavor.setDishId(dishDTO.getId());
            });
​
            dishFlavorMapper.insertBatch(flavors);
​
        }
​
    }

这里的:

 //口味信息也可能是新增的口味,
            flavors.forEach(dishFlavor -> {
                dishFlavor.setDishId(dishDTO.getId());
            });

为什么还要重新设置id?没明白

我的想法:就是修改菜品id,菜品id已知,为什么还需要设置id?

9.sql经常出现的错误:赋值时:比如:update_user = #{updateUser},其中,update_user 是数据库表的字段 ;updateUser是参数

10.springData redis操作redis数据库:

  • 导入springData redis的maven坐标

  • 配置Redis数据源

  • 编写redis的配置类,创建redisTemplate对象

  • 通过redisTemplate操作redis数据库

11.编写redis的配置类:

作用:创建并初始化redisTemplate对象,并返回。(作为bean组件,创建以后可以直接注入)

步骤:

  1. 创建redisTemplate对象

  2. redisTemplate初始化:

    设置redis的连接对象工厂

    设置redis 中 key 的序列化器

  3. 返回redisTemplate对象

其他:

  1. redis的连接对象工厂RedisConnectionFactory是什么?有什么作用?

答:RedisConnectionFactory 是 Spring Data Redis 提供的一个接口,它的作用是创建与 Redis 服务器的连接。你可以把它想象成一个工厂,它的职责是制造(即创建)和管理 Redis 连接。

这个接口的主要目的是抽象化和封装创建 Redis 连接的细节,使得在 Spring 应用程序中使用 Redis 变得更加容易和统一。无论你使用的是哪种 Redis 客户端库(比如 Jedis 或 Lettuce),你都可以通过实现 RedisConnectionFactory 接口来提供连接。

RedisConnectionFactory 的作用包括:

  1. 创建连接:它提供了创建新连接的方法。当你的应用程序需要与 Redis 服务器交互时,它可以通过 RedisConnectionFactory 获取一个连接。

  2. 配置连接:你可以在 RedisConnectionFactory 实现中配置连接的各种参数,比如超时设置、密码认证、数据库选择等。

  3. 连接池管理:在高并发的应用程序中,直接创建和关闭连接是非常耗费资源的。RedisConnectionFactory 可以配合连接池使用,复用连接,提高性能。

  4. 透明化连接管理:开发者不需要关心连接的低级管理,如打开、关闭连接等,这些都由 RedisConnectionFactory 来处理。

在 Spring Boot 中,通常会有一个自动配置的 RedisConnectionFactory 实现,它根据你的 application.propertiesapplication.yml 文件中的配置来创建连接。如果你需要自定义连接的某些特定行为,你可以自己实现 RedisConnectionFactory 接口或者扩展现有的实现类。

简单来说,RedisConnectionFactory 就像是 Redis 连接的“制造商”,它让应用程序能够方便地获取和使用 Redis 连接。

  1. StringRedisSerializer是什么?有什么用?

答:StringRedisSerializer 是 Spring Data Redis 中的一个序列化器,默认情况下,StringRedisSerializer 使用 Java 的 String 类型作为序列化和反序列化的对象。实际上可以接收Object的java类型;

StringRedisSerializer主要用途包括:

  • 键值序列化:在 Redis 中存储键值对时,键和值都需要被序列化为字符串。StringRedisSerializer 可以确保键和值在存入 Redis 之前被正确地转换为字符串格式。

  • 字符串操作:在执行需要字符串参数的 Redis 命令时(如 SETGET 等),StringRedisSerializer 可以确保传入的参数是正确序列化的。

  • 一致性:在分布式系统中,确保所有的 Java 对象在网络传输和存储时使用相同的序列化机制,可以避免数据不一致的问题。

12.关于redis数据库

@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
    log.info("开始创建redis操作对象");
    RedisTemplate redisTemplate = new RedisTemplate();
    redisTemplate.setConnectionFactory(redisConnectionFactory);
    //redis的key的序列化是非常有必要的,否则查询很复杂
    redisTemplate.setKeySerializer(new StringRedisSerializer());
    //但是考虑是否可以切换其他的序列化方法???????
    //因为得到的值仍然是“乱码”
    return redisTemplate;
}

13.在项目中有管理端和客户端和服务端,那么服务端是后端,管理端和客户端是前端,那么在设计接口时有这样的:/api/admin/applications,那么后端怎么根据这个接口开始开发呢?那个api怎么理解,或者说怎么替换?

在软件开发中,API(应用程序编程接口)是一组预定义的函数、协议和工具,用于构建软件应用程序。API 允许不同的软件系统相互交互。在您提到的 /api/admin/applications 接口中,api 通常是指应用程序编程接口的前缀,而后面的路径则定义了具体的资源和操作。

对于后端开发来说,设计和实现这样的接口通常涉及以下步骤:

  1. 理解需求:首先,需要明确接口的目的和需求。在这个例子中,/api/admin/applications 可能意味着这是一个供管理员使用的接口,用于管理应用程序。

  2. 定义资源和操作:确定接口将处理哪些资源(在这个例子中是“applications”)以及支持哪些操作(如获取列表、创建、更新、删除等)。

  3. 设计数据模型:根据接口的需求,设计数据库模型,确定需要存储哪些数据。

  4. 编写路由和控制器:在后端框架中,编写路由来匹配请求的URL,然后编写控制器来处理这些请求。例如,使用 Express.js 框架的 Node.js 应用可能会这样定义路由:

    app.get('/api/admin/applications', adminController.listApplications);
    app.post('/api/admin/applications', adminController.createApplication);
    // 其他路由...
  5. 实现业务逻辑:在控制器中实现具体的业务逻辑,比如从数据库中查询数据、验证数据、处理数据等。

  6. 错误处理:确保接口能够妥善处理错误,并返回适当的错误信息。

  7. 测试:编写单元测试和集成测试来验证接口的功能和性能。

  8. 文档:编写API文档,说明每个接口的用途、请求参数、响应格式和可能的错误代码。

至于“api”如何理解或替换,它通常是一个固定的前缀,用来标识这是一个API接口。在实际部署时,它可能会被替换为实际的域名或子域名,例如 https://api.yourdomain.com/admin/applications。这里的 api 可以被替换为任何符合项目命名规范的前缀,但通常保留 api 是为了明确表示这是一个供外部系统调用的接口。

在开发过程中,后端开发者需要与前端开发者紧密合作,确保接口的设计符合前端的需求,并且能够被前端正确地调用和处理。

14.如果接口都是这样设计的,那么我是不是可以全部取掉api?

在设计RESTful API时,使用 /api 作为前缀是一种常见的做法,它有助于区分API端点和其他类型的URL。然而,是否使用 /api 前缀并不是强制性的,它更多的是一个约定俗成的习惯。以下是一些考虑因素:

  1. 一致性:如果你的团队或项目中已经采用了 /api 作为API端点的前缀,那么保持一致性是很重要的。这有助于团队成员理解和维护代码。

  2. 简洁性:有些开发者和团队可能倾向于更简洁的URL,因此他们可能会选择不使用 /api 前缀。这在小型项目或者内部使用的应用中可能更常见。

  3. 版本控制:在某些情况下,/api 后面可以跟版本号,如 /api/v1,这样可以在不更改现有API路径的情况下引入新版本的API。

  4. 部署考虑:在某些部署环境中,可能需要将API部署在特定的路径下,这时 /api 前缀可以帮助明确API的部署路径。

  5. CORS(跨源资源共享):如果你的API需要支持跨域请求,那么使用 /api 前缀可以帮助你更容易地配置CORS策略。

如果你决定不使用 /api 前缀,你的端点可能看起来像这样:

GET /admin/applications
POST /admin/applications

在决定是否使用 /api 前缀时,你应该考虑你的项目需求、团队偏好以及未来的可维护性。如果你的项目规模较小,或者你预计不会有多个版本的API,那么省略 /api 前缀可能是合理的。但是,如果你预计项目会增长,或者你需要更清晰地区分API端点和非API端点,那么保留 /api 前缀可能是更好的选择。

最后,无论是否使用 /api 前缀,重要的是确保你的API设计遵循RESTful原则,如使用资源名称、HTTP方法和状态码来清晰地表达API的行为。

15.例如,非API端点可能包括:

/:网站的主页。 /login:用户登录页面。 /contact:联系我们页面。 /search:执行搜索的页面或端点。这样的话就是后端不需要对这些api进行开发?

实际上,即使是非API端点,后端通常也需要进行一定的开发工作,因为这些端点可能涉及到服务器端的逻辑处理、数据库交互、用户认证、数据检索等。以下是一些常见非API端点的后端开发任务:

  1. 主页(/)

    • 后端可能需要从数据库中检索特定的内容,如最新文章、推荐产品等。

    • 可能需要处理用户认证状态,以决定显示给用户的内容。

  2. 登录页面(/login)

    • 后端需要处理用户的登录请求,包括验证用户的凭证。

    • 可能需要与数据库交互,检索用户信息。

    • 需要处理会话管理和用户认证。

  3. 联系我们页面(/contact)

    • 后端可能需要处理用户提交的表单数据,如发送电子邮件或存储用户的联系信息。

    • 可能需要验证表单数据的有效性。

  4. 搜索页面或端点(/search)

    • 后端需要处理用户的搜索请求,可能涉及到复杂的查询逻辑和数据库搜索。

    • 需要优化搜索结果,提供相关性和性能。

即使这些端点不直接用于数据的CRUD操作,后端开发仍然需要确保这些端点能够正确地处理用户请求,并提供所需的功能。后端开发不仅仅是关于API端点的开发,它还包括了整个Web应用的后端逻辑,确保应用的稳定性、安全性和可用性。

此外,后端开发还涉及到服务器配置、安全性措施(如防止SQL注入、跨站脚本攻击等)、性能优化、错误处理和日志记录等方面。因此,即使是非API端点,后端开发也是不可或缺的一部分。

*16.在进行开发时会遇到controller同名的时候,这时如果不处理,那么在容器中,组件会发生冲突。具体说明冲突的原因,如何解决冲突?(除了给controller改名字)

17.在接口文档中,如何将用户端和管理端区分开?

在web的配置类中直接:

/**
     * 通过knife4j生成管理端接口文档
     * @return
     */
    @Bean
    public Docket docket1() {
        log.info("准备生成接口文档:");
        ApiInfo apiInfo = new ApiInfoBuilder()
                .title("苍穹外卖项目接口文档")
                .version("2.0")
                .description("苍穹外卖项目接口文档")
                .build();
        Docket docket = new Docket(DocumentationType.SWAGGER_2)
                .groupName("管理端接口")
                .apiInfo(apiInfo)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.sky.controller.admin"))
                .paths(PathSelectors.any())
                .build();
        return docket;
    }

通过 groupName 进行分组,然后就可以在Swagger页面上展示:

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

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

相关文章

如何验证VMWare WorkStation的安装?

如何验证VMWare WorkStation的安装&#xff1f; 右击"网络"&#xff0c;点击 打开"网络和Internet设置"&#xff0c;点击更改适配器选项&#xff0c;如果出现VMNet1和VMNet8&#xff0c;则说明安装成功。

内网穿透(cpolar实现)

目录 一、介绍 二、内网穿透工具cpolar实现 1.下载与安装 2.cpolar指定authtoken 3.获取临时域名 4.验证临时域名有效性 一、介绍 内网穿透&#xff0c;即 NAT 穿透&#xff08;Network Address Translation Traversal&#xff09;&#xff0c;是一种网络技术&#xff0…

Python爬虫使用实例-wallpaper

1/ 排雷避坑 &#x1f95d; 中文乱码问题 print(requests.get(urlurl,headersheaders).text)出现中文乱码 原因分析&#xff1a; <meta charset"gbk" />解决方法&#xff1a; 法一&#xff1a; response requests.get(urlurl,headersheaders) response.en…

java基础-IO(4)管道流 PipedOutputStream、PipedInputStream、PipedReader、PipedWriter

管道 提到管道&#xff0c;第一印象就是水管或者地下管道&#xff0c;一节接着一节&#xff0c;形如下图。 管道流 "流"从上一个管道 ——-> 下一个管道。又细分为字节流和字符流。 字节流&#xff08;PipedOutputStream、PipedInputStream&#xff09; 如果…

SSM框架介绍

SSM通常指的是三个开源框架的组合&#xff0c;即Spring、SpringMVC&#xff08;Spring Web MVC&#xff09;和MyBatis&#xff0c;这三个框架经常一起使用来开发Java企业级应用&#xff0c;特别是在Web应用开发中非常流行。 SSM框架介绍 Spring 简介&#xff1a;Spring是一个…

谷粒商城のNginx

文章目录 前言一、Nginx1、安装Nginx2、相关配置2.1、配置host2.2、配置Nginx2.3、配置网关 前言 本篇重点介绍项目中的Nginx配置。 一、Nginx 1、安装Nginx 首先需要在本地虚拟机执行&#xff1a; mkdir -p /mydata/nginx/html /mydata/nginx/logs /mydata/nginx/conf在项目…

ModuleNotFoundError: No module named ‘mmcv.transforms‘

不得已的解决方法&#xff1a; mmcv升级到2.0.0即可解决 升级后自然又面临一系列不兼容问题&#xff01; 官方文档查漏补缺

【STM32】呼吸灯实现

对应pwm概念可以去看我的博客51实现的呼吸灯 根据对应图我们可知预分频系数为999&#xff0c;重装载值为2000&#xff0c;因为设置内部时钟晶振频率为100MHZ &#xff0c;1s跳 100 000000次 &#xff0c;跳一次需要1/100 000000s 20ms0.02s 对应跳的次数为 我们使用通用定时器…

九,自定义转换器详细操作(附+详细源码解析)

九&#xff0c;自定义转换器详细操作&#xff08;附详细源码解析&#xff09; 文章目录 九&#xff0c;自定义转换器详细操作&#xff08;附详细源码解析&#xff09;1. 基本介绍2. 准备工作3. 自定义转换器操作4. 自定义转换器的注意事项和细节5. 总结&#xff1a;6. 最后&…

【前端学习】AntV G6-07 深入图形与图形分组、自定义节点、节点动画(上、中)

课程链接 AntV G6&#xff1a;深入图形与图形分组、自定义节点、节点动画&#xff08;上&#xff09;_哔哩哔哩_bilibili AntV G6&#xff1a;深入图形与图形分组、自定义节点、节点动画&#xff08;中&#xff09;_哔哩哔哩_bilibili 图形分组 Group | G6 (antgroup.com) 自…

ARM32开发——DMA内存到内存

&#x1f3ac; 秋野酱&#xff1a;《个人主页》 &#x1f525; 个人专栏:《Java专栏》《Python专栏》 ⛺️心若有所向往,何惧道阻且长 文章目录 需求数据交互流程开发流程依赖引入DMA初始DMA传输请求完整代码 关心的内容DMA初始化DMA初始化DMA数据传输请求完整代码 DMA中断开启…

封装智能指针 qt实现登录界面

1.封装独占智能指针——unique_ptr #include <iostream> #include <utility> // For std::move// 命名空间 namespace custom_memory { template <typename T> class myPtr { public:// 使用初始化列表进行初始化explicit myPtr(T* p nullptr) noexcept : …

卡西莫多的诗文集2022-2024.9月6-校庆国庆专版定版

通过网盘分享的文件&#xff1a;卡西莫多的诗文集2022-2024.9月6-A5-校庆国庆专版-定版.pdf 链接: https://pan.baidu.com/s/1cpFK5k1baGXbSGxY30GL_A?pwdjgnt 提取码: jgnt 卡西莫多的诗文集2022-2024.9月6-校庆国庆专版&#xff0c;又稍作修改并勘误了一些错字&#xff0c;…

AWQ量化(Activation-aware Weight Quantization)

论文&#xff1a; AWQ: Activation-aware Weight Quantization for On-Device LLM Compression and Acceleration 中文解读&#xff1a; 深入理解AWQ量化技术 - 知乎 (zhihu.com) 动机&#xff1a;端侧设备用LLM&#xff0c;为了减少显存占用量&#xff0c;所以要用INT4量化&am…

【Jupyter Notebook】汉化

1.打开:Anaconda Prompt 2.输入:"activate Zhui01"(注意&#xff1a;Zhui01是刚创建的环境名字) activate Zhui01 3.输入:"pip install jupyterlab-language-pack-zh-CN" pip install jupyterlab-language-pack-zh-CN 4.打开:Jupyter Notebook 5.点击&q…

Mysql高级篇(中)——七种常见的 join 查询图

注意&#xff1a; MySQL是不支持 FULL OUTER JOIN 这种语法的&#xff0c;因此要实现图中 6、7的查询结果&#xff0c;可以使用 UNION 关键字结合 LEFT JOIN、RIGHT JOIN 实现&#xff0c;UNION可以实现去重的效果&#xff1b; 参考如下代码&#xff1a; -- MySQL中 图标6 的实…

用Unity2D制作一个人物,实现移动、跳起、人物静止和动起来时的动画:中(人物移动、跳起、静止动作)

上回我们学到创建一个地形和一个人物&#xff0c;今天我们实现一下人物实现移动和跳起&#xff0c;依次点击&#xff0c;我们准备创建一个C#文件 创建好我们点击进去&#xff0c;就会跳转到我们的Vision Studio&#xff0c;然后输入这些代码 using UnityEngine;public class M…

MarginNote 4 激活码 - 苹果电脑(Mac)全能型的阅读工具

对广大求学者来说&#xff0c;如何科学有效地掌握知识&#xff0c;一定是大家不懈追求的方向。 众多求学者使用的&#xff0c;深度阅读学习工具 MarginNote&#xff0c;终于为 Mac 推出了官网 4.0 版。带来了众多创新的学习辅助工具。 MarginNote 4 功能简介 1、快速理清各版…

大数据新视界--大数据大厂之Java 与大数据携手:打造高效实时日志分析系统的奥秘

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

探索fastFM:Python中的高效推荐系统库

文章目录 &#x1f680; 探索fastFM&#xff1a;Python中的高效推荐系统库背景&#xff1a;为何选择fastFM&#xff1f;快照&#xff1a;fastFM是什么&#xff1f;安装指南&#xff1a;如何将fastFM加入你的项目&#xff1f;快速入门&#xff1a;五个基础函数的使用实战演练&am…