Spring Boot 项目如何实现上传头像功能?
目录
设计思路
效果展示
编辑
分析
前后端交互接口
请求
响应
代码实现和详细注释
数据库设计
自定义资源映射
前后端交互
客户端开发
服务器开发
设计思路
效果展示
分析
实现这个功能只要弄清楚以下几点即可:
- 怎么将头像数据发送给服务器,设定怎样的数据类型?我们可以使用 form 表单将数据进行发送,表单设定格式为 enctype="multipart/form-data"(这也是为什么不直接用 ajax 请求后端,因为 ajax 发送请求的数据格式很难设置成这个数据格式),使用 type="file" 的 input 控件并搭配 type="submit" 的 input 控件来实现用户头像的上传。
- form 表单提交数据后,怎么接收服务器的响应?使用 FormData 对象来控制 form 表单,通过 FormData 对象的 append 方法即可将 input 控件中的头像数据保存到 FormData 对象中,这时候我们便可以使用 ajax 的方法请求后端,就可以接收服务器响应啦,请求中的数据便是 FormData 对象(相当于对 form 表单的一层封装,只是用其格式类型),这时还需要注意,一定要将 contentType 和 processData 属性设为 false,这样才能避开 ajax 默认发送格式,而使用 form 表单设置的发送数据格式。
- 服务器如何搭配数据库保存头像数据?数据库不需要完整的将图片数据保存下来,具体如何实现呢,我们可以通过 transferTo 文件操作将图片保存到我们本地磁盘上,然后图片保存的绝对路径以字符串的形式保存到数据库即可(使用 UUID 生成随机字符串保存,否则可能会因为重名而覆盖图片文件)。这样,每次读取图片,通过这个路径即可(注意:最后这句话是一个误区,后面会分析原因)。
- 服务器保存头像后浏览器即使刷新,头像也没有发生变化?因为浏览器禁止 js 访问本地磁盘,而我们在数据库中保存的是头像的绝对路径,那么肯定是读取不到的。怎么办呢?我们可以设置两个路径,一个是绝对路径(供服务器保存头像),一个是相对路径(供浏览器访问头像),因此数据库保存头像的相对路径即可。
- 明明按照以上步骤在浏览器上传了图片并保存到了本地磁盘,但是页面图片还是没有更新,需要重启服务器后才会更新图片?这是因为浏览器在界面上传图片,而 Spring Boot 程序是感知不到的,因此需要我们去设定自定义资源映射(具体的,往后看~)。
前后端交互接口
请求
POST /user/subphoto
Content-Type: multipart/form-data
processData: falsedata: new FormData(document.querySelector("#forminfo")) //form 表单对象
响应
HTTP/1.1 200 OK
Content-Type: application/json{"code": 200,"msg": "","data": photoPathRelative //图片相对路径
}
代码实现和详细注释
数据库设计
create table userinfo(id int primary key auto_increment,username varchar(100) unique,password varchar(65) not null,photo varchar(500) default "img/default.jpg",createtime timestamp default current_timestamp,updatetime timestamp default current_timestamp,`state` int default 0,nickname varchar(50) not null,realname varchar(50) default "",idcard varchar(50) default "",gitee varchar(200) default ""
) default charset 'utf8mb4';
自定义资源映射
创建一个类,名为 StaticResourcesConfig,实现 WebMvcConfigurer 接口下的 addResourceHandlers 方法,此方法就是用来注册路由的。
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration //一定不要忘了这个注解
public class StaticResourcesConfig implements WebMvcConfigurer {/*** 自定义资源映射* 由于在浏览器界面上传图片,而 Spring boot 程序是感知不到的,因此需要自定义资源映射* @param registry*/@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/upload/**").addResourceLocations("file:upload/");}
}
addResourceHandler("/upload/**"):表示访问的时候路径上要加上upload,不然访问不到。
addResourceLocations("file:upload/"):你图片上传的路径,我的图片上传就在upload文件中。
前后端交互
客户端开发
//隐藏修改头像和提交控件jQuery("#choose-photo").hide();jQuery("#sub-photo").hide();//修改头像function updatePhoto() {//点击头像,就会弹出文件选择框jQuery("#choose-photo").click();//当 #choose-photo 内容改变时触发jQuery("#choose-photo").change(function () {// //点击 submit 提交表单var fd = new FormData(document.querySelector("#forminfo"));fd.append("myphoto", jQuery("#choose-photo").val());jQuery.ajax({type: "POST",url: "/user/subphoto",data: fd,// 想让文件传输格式为 form 表单设置的格式,那么就必须设置以下两个属性contentType: false,processData: false,success: function (result) {if (result != null && result.code == 200) {//刷新网页alert("头像修改成功!");location.href = location.href;} else {alert("头像上传失败,请稍后重试!");}}});});}
服务器开发
/*** 修改用户头像* @param request* @param photo* @return*/@RequestMapping("/subphoto")public AjaxResult updatePhoto(HttpServletRequest request,@RequestPart("myphoto") MultipartFile photo) {//非空校验if(photo == null) {return AjaxResult.fail(403, "图片错误!");}//要上传的文件名String originalFileName = photo.getOriginalFilename();//获取用户信息(1.删除旧头像需要原来的旧头像的路径 2.修改图片需要用户 id)UserInfo userInfo = UserSessionUtils.getUser(request);if(userInfo == null || !StringUtils.hasLength(userInfo.getUsername()) ||!StringUtils.hasLength(userInfo.getPassword())) {return AjaxResult.fail(403, "参数错误!");}if(!userInfo.getPhoto().equals("img/default.jpg")) {//不是修改默认头像的话就将旧头像删除即可File file = new File(AppVariable.IMG_PATH_ABSOLUTE+ userInfo.getPhoto().split("/")[2]);file.delete();}//获取文件后缀String suffix = originalFileName.substring(originalFileName.lastIndexOf("."));//生成图片名称,使用 UUID 避免相同图片名冲突,加上图片后缀String photoName = UUID.randomUUID().toString() + suffix;//图片保存路径(绝对路径/相对路径)//这里为什么还要用相对路径,只用绝对路径不行么?//因为禁止浏览器访问本地磁盘绝对路径路径,因此最简单的办法就是配置一个绝对路径用来保存文件,一个相对路径提供给浏览器访问String photoPathAbsolute = AppVariable.IMG_PATH_ABSOLUTE + photoName; //绝对路径String photoPathRelative = AppVariable.IMG_PATH_RELATIVE + photoName; //相对路径//生成文件(绝对路径)File saveFile = new File(photoPathAbsolute);try {//将上传文件绝对路径保存到服务器文件系统photo.transferTo(saveFile);//保存图片相对路径到数据库中userService.updatePhotoById(userInfo.getId(), photoPathRelative);//修改评论userInfo.setPhoto(photoPathRelative);updateInfoUtils.updateSessionAndComment(request, userInfo);} catch (IOException e) {e.printStackTrace();}//将图片相对路径返回给前端return AjaxResult.success(photoPathRelative);}
Spring Boot 项目如何实现上传头像功能?相关推荐
- 解决使用Spring Boot、Multipartfile实现上传提示无法找到文件的问题
解决使用Spring Boot.Multipartfile实现上传提示无法找到文件的问题 参考文章: (1)解决使用Spring Boot.Multipartfile实现上传提示无法找到文件的问题 ( ...
- 在项目中使用 Discuz!NT的上传头像功能
大概半年前,由于某个网站项目需要整合Discuz!NT,就粗略的用了一下.觉得里面的会员上传头像功能方便好用,而且支持摄像头,就把它的代码分离出来,以后用在需要的地方. 用过Discuz!NT的朋友会 ...
- php拍视频上传,php视频拍照上传头像功能实现代码分享
现在手机拍照很火,那么如何使用手机拍照并上传头像呢?原因很简单,就是数据传递,首先手机传递照片信息,既不是post传递也不是get函数传递,这个另外一种数据 如果要在php中实现视频拍照我们需要借助于 ...
- php更换wordpress用户头像,WordPress如何添加用户自定义上传头像功能
使用WordPress建站的朋友应该知道,WordPress本身是没有上传自定义头像功能的,如果要更换头像,步骤是非常麻烦的. 而在我们开发一款WordPress主题中,特别是多用户的主题,让注册用户 ...
- php拍照,php视频拍照上传头像功能实现代码分享
php视频拍照上传头像功能实现代码分享 发布于 2016-01-19 07:47:53 | 121 次阅读 | 评论: 0 | 来源: 网友投递 PHP开源脚本语言PHP(外文名: Hypertext ...
- flask上传头像功能
上传头像功能只需要以下N步: 首先我们要从HTML中获取头像文件 获取后,传入视图函数 # user.py # 修改用户头像功能 @user_blu.route("/user/avatar& ...
- php上传头像的代码,php视频拍照上传头像功能实现代码分享
如果要在php中实现视频拍照我们需要借助于flash插件了,由flash拍出的确照片我们再通过php的$GLOBALS ['HTTP_RAW_POST_DATA']接受数据,然后保存成图片就可以了,下 ...
- spring boot + vue实现图片上传及展示
余近日开发spring boot +vue的后台管理项目,涉及到文件上传功能,使用之前项目的文件上传模块,一直有问题.遂经过两天的百度,加个人理解,最终解决了基本的文件上传功能. 首先,html页面: ...
- Spring Boot 实现多图片上传并回显,涨姿势了~
上传 Controller的代码非常简单,由于用了SpringMVC框架,所以直接用MultipartFile来接即可.由于是多图片上传所以用数组来接.此处应该注意参数名应该和<input> ...
最新文章
- 504. Base 7
- 基于云平台的家居综合监测管理系统的设计与实现
- ADC内设与外设的区别
- 遗传相似系数怎么计算_如何计算遗传变异系数
- tensorflow 的版本差异与变化
- 什么是语音技术及其应用?语音识别的研究意义与进展
- [python+pip] 使用pip将函数库安装到Python环境或Anaconda环境
- bat脚本 拷贝文件/文件夹到目标目录
- 西安电子科技大学计算机学院数据结构真题,数据结构1800题(标准答案全)
- 蓝桥杯单片机第九届 省赛 彩灯控制器
- tortoise git 冲突解决
- 计算机应用基础补考申请书,院级教改课题申请书计算机应用基础教学.doc
- 是时候该深入解析java虚拟机:编译概述,编译理论基础了
- qnap直接用linux命令,QNAP之如何使用第三方百度网盘挂到nas上下载
- FlexRay总线原理及应用
- 定时器软件RH Timer for Mac了解一下
- Azure DevOps —— Azure Artifacts 包管理平台
- Sequelize ORM
- LeetCode:309. 最佳买卖股票时机含冷冻期(python)
- uni-app 微信小程序提示音一闪而逝