该贴将记录笔者在学习该项目时遇到的问题及解决方法、笔记、想法和工作日志

# Day 1

# 初始环境的问题以及解决方案

第一次运行这个项目的人,基本上会遇到初始环境启动问题。

  • 前端,注意你的 80 端口是否被占用以及 nginx 文件是否放在了全英文文件夹下面
    如果你的 80 端口被占用,可以去修改 nginx. conf 下的端口,比如我就该为了 81,在启动服务器的时候进入的网站也要跟着你的端口号去修改

  • 后端环境与数据库
    后端环境问题有两个,你需要先看自己的 maven 能不能编译出来,如果编译不出来,大概率是因为 Lombok 工具包没有打上,这里你要去找最新的版本号,去每一个 pom. xml 文件的依赖部分添加。

另一个可能出现的问题是,Java 版本号不对 java: 错误: 不支持发行版本 5

解决这个问题的关键在于调整你的版本号,上面图片紫色图标右边点击数字可以切换版本,全部改为 1.8 应该就可以跑起来了

  • 数据库连接问题
    你大概率连接不上数据库,因为初始工程的密码跟你的 MySQL 的密码大概率是不一样的,找到你的 application-dev.yml ,把密码和账号改为自己的就可以连接上了,另外前提肯定是你安装了 MySQL,还有 idea 本身支持导入数据库。

# nginx 反向代理

前端请求地址与后端的接口地址不一样,前端动态请求通过 nginx 转发到了后端服务器

好处:

  • 提高访问速度
  • 负载均衡 —— 降低单台服务器的压力
  • 保证后端服务安全,后端服务不对外开放

前端的 /api/ 经过 nginx 转化为配置的路径

# 接口

接口一般是在项目开始写之前就确定好的,跟信息办对接的时候,我可以自己尝试去写写接口文档

# Swagger

Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务 (https://swagger.io/)。它的主要作用是:

  1. 使得前后端分离开发更加方便,有利于团队协作

  2. 接口的文档在线自动生成,降低后端开发人员编写接口文档的负担

  3. 功能测试

# Lombok

有的时候,识别不到 get 和 set 函数,这个时候可以把 maven clean 重新编译

# Day 2

# 新增员工 ——500 错误码

遇见错误码,先检查控制台,这种情况下大概率是 sql 语句写错了

这里我就是把 id 属性 insert 了,实际上 id 会在数据库上自动填充

# 代码完善

录入重复的值,数据库唯一约束重新出现的处理 —— 全局异常处理器

# ThreadLocal

Q:如何获取当前登录账号的 id?
A:从 jwt 令牌上解析出来

# 员工编辑

没有在 controler 层传入 @RequetBody 这类注解,导致 200 但是没有修改成功

# Mapper xml 文件配置错误

在写新增分类的时候,我只留了一个空的 xml 配置文件,于是报错了。

修正的办法就是把 xml 需要的基本信息填上

1
2
3
4
5
<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sky.mapper.CategoryMapper">
<!-- Your mapping statements here -->
</mapper>

# 手戳分类接口遇到的问题

  1. 没有注意到一些可能的出错,菜品分为套餐和单菜,菜品如果关联了套餐,那么删去菜品应该是一个业务异常
  2. 复杂的 SQL 还是得写到 xml 文件上去
  3. 注意传入的参数和需要传出的参数

# Day 3

# 问题:如何实现公共字段自动填充?

实现步骤:

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

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

3). 在 Mapper 的方法上加入 AutoFill 注解

通过注解来实现,很有意思,这就是面向注解编程?

# 刷课与写代码的思考

前面是我之前学过的内容,开始出现新的知识我就更不上了,现在是打算先刷完理解完,再开始写代码,应该效果会更好

# 文件上传的配置

报错了一下代码

1
2025-03-19 17:07:51.827 WARN 36248 --- [nio-8080-exec-6] com.aliyun.oss : [Server]Unable to execute HTTP request: 返回结果无效,无法解析。 [ErrorCode]: InvalidResponse [RequestId]: 67DA89671171CD3234C8E6C0 [HostId]: null [ResponseError]: <?xml version="1.0" encoding="UTF-8"?> <Error> <Code>AccessDenied</Code> <Message>You have no right to access this object because of bucket acl.</Message> <RequestId>67DA89671171CD3234C8E6C0</RequestId> <HostId>sky-out-zarathu.oss-cn-shanghai.aliyuncs.com</HostId> <AccessDeniedDetail> <PolicyType>ResourceGroupLevelIdentityBasedPolicy</PolicyType> <AuthPrincipalOwnerId>1714730636296908</AuthPrincipalOwnerId> <AuthPrincipalType>SubUser</AuthPrincipalType> <AuthPrincipalDisplayName>205048742374127396</AuthPrincipalDisplayName> <NoPermissionType>ImplicitDeny</NoPermissionType> <AuthAction>oss:PutObject</AuthAction> <EncodedDiagnosticMessage>AQIBIAAAAAXk6QgsKp+RYlwgCW666r1JkbmrSdNMn1Kb0yJGFEQ/0K8DAZmABfew77VxtxSXLWNCLI9/s4RLehxiDvAc40iWO+2kxpU23lFBemcVX+vPOWkokr36KMMzxgb97aLdm/1YWBkvZT0C6ZFjHsc6XaEb0ViXOSWccswWsoXp1Il8eMjlJuuUuxCUThgsBtSfXzEAgZw2WH4sL10CJeTGusHVjILyRpADuM50tY0Si1zuufYPuqBvVcP7F5tcdFhsKGVmyW7UJHxnTxON3pJfVFCy4YaUX0Fklav+iOxeO3ohIiM+Yg8LWfRz4TO5rCpY7Bpk/KM5SP5rHRIIf0L+G5FEq/Qb9Rcf8050X7ZQ2I5aFyN4dAfgxw1hbFtOULG9P/Z/lOYrAiaHq3on2v8mpLX5P6PR6hsUUK2crXkOp1UYKAF5R6rOuZVTmovMoCGdym+2LXWHhLpCeJpY/2BoDQceeFNcbecSasfVjMyQb5axvj3Ep5NQ/GCU7XxuY+O/UlKo/Di8SOM0zBGOJh8wz+saDfEdhv9/+rIEY+z0ClmIT+NncQjcSwZ8fVnHqlIAdMl3FvgXFiXKVnqva46eFbp6ZNvmAwO1Y6ifaT47ZseQ0ClK7BAU3oFI80Z8pnHNlu3ZjTKiZU0KYHGXn1tKnIq11Q5PeubUSlxRQthtyJpAbpGzB1hnqADuI2Ryzbv/lAB4KX2iqdEadfik/gjIK+7fNk3e/7k7+6Hw/mxn8arg3+l0pGwgG81Jrs98mCizOdsbWa7howlTVu7Uy4uhBHBTgqvaIzZhlCUoCL0Sx8+EOHV1q+ZUlznwfxiPc7x6LFv98P0E8COjjwbXQVq7XFco/5sy8CO/J2kWJeg7cX2ak+nr+SveprCfpTcMZ61+vQ==</EncodedDiagnosticMessage> </AccessDeniedDetail> <EC>0003-00000001</EC> <RecommendDoc>https://api.aliyun.com/troubleshoot?q=0003-00000001</RecommendDoc> </Error> Caught an OSSException, which means your request made it to OSS, but was rejected with an error response for some reason. Error Message:返回结果无效,无法解析。 Error Code:InvalidResponse Request ID:67DA89671171CD3234C8E6C0 Host ID:null 2025-03-19 17:07:51.827 INFO 36248 --- [nio-8080-exec-6] com.sky.utils.AliOssUtil : 文件上传到:https://sky-out-zarathu.oss-cn-shanghai.aliyuncs.com/aa6588d7-3049-4cfd-9d21-36fd9e493b7d.jpg

最后检查出问题是权限没有给够,很奇怪,我之前用的云账号 AccessKey 没有出错,后面按照 deepseek 的建议,改用了 RAM 用户 AccessKey,在操作栏下面点击添加权限

在此之前应该要重启一下 IDEA,重新运行 Java 程序

重新填上配置信息后就成功了

# 幽默 debug(新增菜品功能)

1
2
3
//获取insert语句生成的主键值  
dishMapper.insert(dish);
Long dishId = dish.getId();

这里要先进行插入,自动生成后才能 get 到 id

debug 的时候尤其要注意是否有 null 的存在,遇到问题可以去弹幕看看别人的提示

# 业务逻辑

除去最基本的增删改查,代码功能开发的时候还需要注意业务的需求与规则

比如菜品的业务规则:
起售中的菜品是不能够被删除的,被套餐关联的菜品不能被删除

开发的时候要多注意一些细节,防止在业务上线后出现漏洞

# Day 4

写根据分类查询菜品接口的时候参数没成功传进去,检查出来是在 controller 层传入的参数要与请求参数的名字对应,才能成功赋值


这里我最开始用的是 id,debug 发现 id 的值变成了 null,把 id 改为 categoryId 后问题解决了

# Day 5 (实战)

@RestController  注解不接受任何参数。您尝试像  @RequestMapping  那样传递路径参数给它,这是不正确的。

1
2
3
@RestController  // 无参数
@RequestMapping("/admin/setmeal") // 路径应该在这里指定
@Slf4j

错误写法:
1
2
@RestController("/admin/setmeal")
@Slf4j

写业务代码很重要的一点就是要理清楚表与表之间的关系,我的 serviceImpl 应该是对表进行什么样的操作?

涉及多个表的操作要记得加上 @Transactional 注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//新增套餐  
@Transactional
@Override
public void addSetmeal(SetmealDTO setmealDTO) {
Setmeal setmeal = new Setmeal();
BeanUtils.copyProperties(setmealDTO,setmeal);
setmeal.setStatus(StatusConstant.DISABLE);
setmealMapper.addSetmeal(setmeal);

List<SetmealDish> setmealDishes= setmealDTO.getSetmealDishes();

//获取生成的套餐id
Long setmealId = setmeal.getId();

setmealDishes.forEach(setmealDish -> {
setmealDish.setSetmealId(setmealId);
});

setmealDishMapper.save(setmealDishes);
}

还需要注意对表操作的先后顺序

例如在这段业务代码上, setmealDish 需要套餐的 id,因此先对套餐表进行插入操作,再从套餐表获取 id 值,通过 forEach 和 set 函数将 id 放入 setmealDish

# Day 7

减少数据库的流程和逻辑

缓存逻辑分析:
每个分类下的菜品保存一份缓存数据
数据库中的菜品数据变更的时候及时把缓存数据清理掉

# 完结感想

# 我的收获

  • 学会了怎么看接口文档,如何根据接口文档开发
  • 初步学会了如何设计接口
  • 了解了 spring 框架下的诸多小组件?spring task 等等
  • 初步了解了 redis 的概念以及使用
  • 熟悉了简单业务逻辑代码的写法
  • 基本理解了前后端代码是如何进行互动的
  • more

# 我的想法

我学习苍穹外卖主要是为了应对我手上的 web 开发的项目,但我并不是很想 all in Java 开发,我觉得这样做直接就限制死了自己的路,我还想探索更多的路。所以在后期进行这个项目的学习的时候,我并不会太在意细节,我觉得没有必要去强行要求自己学过了这个项目,整个项目都要闭着眼睛写出来,这个是没有必要的,对我而言更重要的是理解 web 后端开发中的各个流程,可能要用到的技术和软件有哪些,我以后可以做到借助 ai 进行快速的开发就行了。当然,还有学会了怎么使用 maven,以及还有一堆的 debug 的办法,这样的 debug 还是跟 61 b 的 debug 有些不同,还有知道可以借助状态码来定位 bug,比如 500 一般是数据库错误,401 是令牌校正出错,404 可能是服务器没启动等等。学会这些对于我以后利用 ai 开发是很有帮助的,极大地减少我 debug 的效率。