第一章 环境搭建
第二章 项目运行
第三章 阅读源码:例子-新增用户接口
第四章 基于ruoyi-vue开发新项目
本文主要是学习项目功能接口的代码:新增用户的功能接口。
按F12 或 (页面上右键 → 检查) → 打开开发者调试界面 → 设置
设置按钮右边的按钮 → 设置停靠侧
保持 调试窗口-网络 打开 →进入用户管理 → 可以看到一堆请求 → 点击按钮清屏
点击 新增 → 填写信息并确定(确定前再清屏一下) → 下方显示我们刚才从前端发送的新增请求user
在前后端快速找到对应代码的方式就是ctrl+shift+F
快捷键全局搜索 部分请求URL
,在这之前如遇到快捷键没反应则要先把输入法–设置–按键–下图热键关闭(解决快捷键冲突)
回到正题,前端在vscode中全局搜dev-api/system/user
(发现没有,不慌),我们退一步搜/system/user
,出来了一堆结果,必然跟在url:后面的、最匹配的只有两个 → 点开来看 → 发送新增用户请求的前端代码就找到了!在上面我们得知请求方式为POST,所以下方这两个请求是不一样的!
接下来我们看下前端代码:
// 新增用户
export function addUser(data) { //data封装的是我们输入的信息,传给后端insert到用户表中
return request({ //request函数在这里只是被传入参数调用,显然是一个在别处定义好的函数
url: '/system/user', //传入url
method: 'post', //传入请求方式
data: data //传入data
})
}
发送请求的request函数在何处定义?我们双击选中request → ctrl+F
(文件内查找) → 发现文件头部的引入代码import request from '@/utils/request'
得知引入的是utils目录下的request.js文件 → 在项目文件中找到并打开 → 找到request请求函数定义的地方(想更多了解下面的前端知识点的需自行百度补习,一些逻辑确实比较晦涩难懂,在这里放出来是为了让大家有一些阅读代码的思路,追根溯源~):
// request拦截器
service.interceptors.request.use(config => { //vue中axios请求拦截器(在请求之前进行一些配置)
// 是否需要设置 token(这块逻辑可以百度下,有作者亲自解答的~)
const isToken = (config.headers || {}).isToken === false
// 是否需要防止数据重复提交
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
if (getToken() && !isToken) {
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
}
// get请求映射params参数
if (config.method === 'get' && config.params) {
let url = config.url + '?' + tansParams(config.params);
url = url.slice(0, -1);
config.params = {};
config.url = url;
}
if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
const requestObj = {
url: config.url,
data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
time: new Date().getTime()
}
const sessionObj = cache.session.getJSON('sessionObj')
if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
cache.session.setJSON('sessionObj', requestObj)
} else {
const s_url = sessionObj.url; // 请求地址
const s_data = sessionObj.data; // 请求数据
const s_time = sessionObj.time; // 请求时间
const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交
if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
const message = '数据正在处理,请勿重复提交';
console.warn(`[${s_url}]: ` + message)
return Promise.reject(new Error(message))
} else {
cache.session.setJSON('sessionObj', requestObj)
}
}
}
return config
}, error => {
console.log(error)
Promise.reject(error)
})
大家一定要善用
CTRL+F
和CTRL+SHIFT+F
去搜索!
上面没看懂没关系,我再总结一下:前端通过url路径+请求方式post,把用户输入的数据封装在data精确的传到后端对应的方法中,再进行后续的处理!
补充内容:理一下思路,发送新增请求是我们在页面点击 新增 按钮 → 弹框,填入数据 → 点击确定 → 触发与 确定 按钮绑定的方法 → 该方法中执行发送请求的方法,选中addUser → ctrl+shift+F 这样就找到了新增按钮相关的前端代码了!
补充内容:可以看到大佬把新增和修改的确定按钮绑定的方法写在了一起,通过判断表单数据中 userId是否为未定义类型(可以理解为 无此值)来选择发送不同的请求,ctrl+F搜submitForm → 看到@click="submitForm" → 显然它就是 确定 按钮绑定的方法!(前端样式的代码、语法太多,这里就不展开了,可自行百度补习~)
接下来再回到浏览器:
切换到 载荷 → 请求载荷即是我们输入的数据(封装在data)
切换到 预览 → 预览即是后端返回来的数据(格式化数据结构后的数据)
切换到 响应 → 响应也是后端返回来的数据(原始数据)
前面提到过,在前后端快速找到对应代码的方式就是ctrl+shift+F
快捷键全局搜索 部分请求URL
,所以我们在idea搜索下/system/user
(双击打开):
然后打开 SysUserController(Controller一般用于拦截前端发来请求) → 往下拉找到新增用户的方法:
/**
* 新增用户
*/
@PreAuthorize("@ss.hasPermi('system:user:add')")
//@PreAuthorize注解,是进入方法前的权限验证,声明这个方法所需要的权限表达式
@Log(title = "用户管理", businessType = BusinessType.INSERT)
//@Log注解,大佬自定义的操作日志记录注解
@PostMapping
//@PostMapping注解:映射一个POST请求
public AjaxResult add(@Validated @RequestBody SysUser user)
{
if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user.getUserName())))
{
return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
}
else if (StringUtils.isNotEmpty(user.getPhonenumber())
&& UserConstants.NOT_UNIQUE.equals(userService.checkPhoneUnique(user)))
{
return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,手机号码已存在");
}
else if (StringUtils.isNotEmpty(user.getEmail())
&& UserConstants.NOT_UNIQUE.equals(userService.checkEmailUnique(user)))
{
return AjaxResult.error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在");
}
user.setCreateBy(getUsername());
user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
//这里可以看到,我们下一步需要调用userService里的insertUser方法!
return toAjax(userService.insertUser(user));
}
我们下一步需要调用userService
里的insertUser
方法,所以我们下一步要先找ISysUserService(按住CTRL+鼠标点击userService → 发现private ISysUserService userService; → 再次CTRL+鼠标点击
ISysUserService` )
在ISysUserService
里CTRL+F搜索insertUser
ISysUserService(Service一般都是业务层接口,会有对应的ServiceImpl实现类)
所以我们全局搜索ISysUserService
→ 找到对应的实现类SysUserServiceImpl
实现类要实现接口的方法,所以接着,文件内搜索insertUser
→ 发现结果太多,通过区分大小写+全字匹配筛选结果
这里我们又可以得知下一步调用的是userMapper里的insertUser方法(Mapper一般为数据层接口,我们终于要开始对数据库进行操作啦!)
@Override注解:系统会帮你检查该方法是否重写了父类方法
@Transational注解:表明该方法具有事务属性
依旧是CTRL+左键
点击userMapper
→ 继续点SysUserMapper
→ CTRL+F
搜索insertUser
(接口里写的都是方法声明,而一般数据层Mapper是通过Mapper.xml来实现数据库操作的!)
so,我们CTRL+SHIFT+F
全局搜SysUserMapper
→ 找对应的Mapper.xml文件
在SysUserMapper.xml里CTRL+F
搜索insertUser
→ 找到该方法sql语句
至此,我们基本上已经把新增用户功能接口的所有代码都找出来了!
总结一下:后端拦截到前端的请求后,相应的Controller的方法接收前端传来的data(我们输入的数据) → 调用业务层Service接口 → ServiceImpl实现接口具体的业务逻辑 → 调用数据层Mapper接口 → 通过对应的Mapper.xml文件,执行对应的SQL语句 → 对数据库进行操作
最后我们看下数据库:
打开navicat → sys_user表 → 数据已经插入成功 → 回到浏览器,新数据已经显示在页面上了!
文章更偏重的是 阅读项目中相应功能代码 的一个思路,或许有不少写得不好的地方,请大家多多谅解,后续会一边学习该项目一边更新博客,希望跟大家一起共同进步!
直通车~
第一章 环境搭建
第二章 项目运行
第三章 阅读源码:例子-新增用户接口
第四章 基于ruoyi-vue开发新项目