在日常开发中,总会遇到上传文件、图片等功能,然后本地开发的话,又没有像OSS、七牛等网络存储,这个时候通常将文件上传到本地,那么上传之后拿到的是本地的路径,存储到数据库中,查询的时候如何将本地的图片进行一个回显到页面上,最初想的
-可以通过base64的方式,查询数据的时候直接将本地图片转换成base64返回然后显示到页面中
-也可以通过在数据库中存储图片名称,然后通过后端一个接口专门接受图片名称,返回图片流或者base64
虽然也能通过上述说的方式解决这儿问题,但总觉得不太方便和友好,那如何在本地开发的时候能更优雅的解决上传文件回显这些问题呢?
最近在使用若依框架时,突然想看看若依是怎么解决这个上传和回显问题的, 接下来就跟我一起去研究一下吧!
若依框架中的上传
首先下载下来的若依框架除了上传头像外,没有其他的上传功能,但是在前端的代码中有封装好的上传图片和上传文件的组件。所以这里暂时就以上传头像做为切入点 !封装好的上传文件和图片咱们放到最后再说,原理基本一致!
点击上传图片之后,请求的接口是:http://localhost/dev-api/system/user/profile/avatar, 然后上传成功后返回了一个/profile/avatar/2024/12/24/a54fead71fadeea5edb27e5031a694ec_20241224111039A001.jpg文件路径, 这个路径会被存储到数据库中,后续回显都会基于这个路径来
然后点击上传头像之后,发现他请求了一个 http://localhost/dev-api/profile/avatar/2024/12/23/880f56db47946db499fc02d311aa4335_20241223173013A001.jpg 的地址, 这里就是图片上传成功之后能回显的关键所在!
- 首先请求这个接口是哪里的?
- 其次这个接口是如何拿到存储在本地的图片信息的?
- 首先可以在前端项目中的.env.development文件中看到关于dev环境的配置
- 然后在vue.config.js中看到,将localhost/dev-api/映射成了 localhost:8080
- 所以回到问题1, 请求的http://localhost/dev-api/profile/avatar/2024/12/23/880f56db47946db499fc02d311aa4335_20241223173013A001.jpg地址其实映射完成之后是: http://localhost:8080/profile/avatar/2024/12/23/880f56db47946db499fc02d311aa4335_20241223173013A001.jpg
- 但是接下来又发现一个其他的问题, 映射之后的这个接口在后端代码中找不到,后端找不到没有/profile开头的接口
- 然后如果接口没有的话,那肯定会有对应的各种拦截器去处理的,所以就会在对应的代码中找到如下一个拦截器
ResourceHandlerRegistry是Spring MVC框架中的一个类,用于注册和管理静态资源处理器(ResourceHandler)。它提供了一系列方法用于配置和操作静态资源。
可以发现在ResourceHandlerRegistry中注册了一个静态资源处理器和配置了静态资源的位置, 这个方法会把/profile开头的路径给替换掉 RuoYiConfig.getProfile() 会获取到 最初的文件根路径D:/ruoyi/uploadPath
会自动转向到 RuoYiConfig.getProfile() 目录下寻找对应的资源文件,也就找到了请求文件最后返回file:D:/ruoyi/uploadPath/avatar/2024/12/23/880f56db47946db499fc02d311aa4335_20241223173013A001.jpg文件流。
然后对照上述的接口发现,哦,原来是通过这里进行的一个接口映射到本地静态资源的呀!
真是一个好的思路呢!到这里图片回显的问题就清晰了!接下来是贴一下若依的上传下载的代码!
前端代码:
前端这里提供了上传文件、上传图片、预览图片的组件,若依已经封装好了,并且也已经进行了全局的声明,可以直接使用,使用的时候别忘记指定绑定的值即可。
<image-upload v-model="form.${field}"/>
<file-upload v-model="form.${field}"/>
<image-preview :src="scope.row.${javaField}" :width="50" :height="50"/>
然后上传调用的是后端的common/upload接口
后端代码:
java
// 上传并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file);
这里代码将文件上传并生成一个新的路径: /profile/avatar/2024/12/24/a54fead71fadeea5edb27e5031a694ec_20241224111039A001.jpg
然后数据库中存储的就是该路径,回显的时候该路径会通过上面的静态资源处理器转换成对应的本地路径对应的文件流!
至此, 若依的上传文件及回显功能,算是彻底搞明白了!的确是一个很好的思路。学习到了!