六、上传头像功能的实现
上传头像功能的实现
用户上传头像图片,涉及到的问题:图片在数据库中以何种形式存在?
文件上传保存在服务器的某个位置,只需要将该位置记录即可,即数据库中对应字段存储的是头像图片在服务器中的存储路径
在实际应用场景中,一般是将静态资源文件(图片、视频、文本文件等资源文件)存储在一台专门的电脑上,将该电脑作为一个单独的服务器使用
持久层
规划SQL语句
将用户头像存储路径更新到数据库表中的avatar字段,本质为一条更新语句
| 1 | update t_user set avatar=?,modified_user=?,modified_time=? where uid=?; | 
抽象接口和方法
在UserMapper接口定义对应的抽象方法
| 1 | /** | 
抽象方法配置到映射文件UserMapper.xml
| 1 | <update id="updateAvatarByUid"> | 
单元测试
| 1 | 
 | 
业务层
规划异常
- 打开页面时,可能找不到用户的信息或用户已被删除
- 信息插入过程中发生未知错误
前面的功能以前模块已经实现对应代码
抽象接口和方法
在 IUserService接口中编写对应的抽象方法
| 1 | /** | 
抽象方法实现
| 1 | 
 | 
单元测试
| 1 | 
 | 
控制层
异常处理
业务层的两种可能异常,在以前功能模块中,控制层异常处理类中均有对应的逻辑处理
由于文件上传过程中可能由于大小、格式、类型等错误引发异常,所以需要专门规划文件上传的异常
| 1 | FileUploadException: 泛指文件上传异常,基类,继承自RunTimeException | 
在控制层异常处理基类中定义对应的异常逻辑(不同的异常,基于不同的状态响应码)
| 1 | 
| 1 | else if (e instanceof FileEmptyException) { | 
设计请求
| 1 | request url: /user/alert_avatar | 
处理请求
| 1 | /** 设置上传文件的最大值 10MB */ | 
前端页面
直接通过表单发送请求
| 1 | <!--上传头像表单开始--> | 
部分功能优化和Bug解决
更改SpringMVC默认文件大小
方式一:在配置文件application.yaml里修改
| 1 | spring: | 
方式二:采用Java代码修改上传文件大小限制,在主类中进行配置,可以定义一个方法,用@Bean修饰,在类的前面添加@Configuration修饰,该方法返回值类型`MultiPartConfigElement
| 1 | 
 | 
页面图像显示
通过ajax发送请求,解析数据,设置到image对应标签进行数据展示
前端表单数据映射
- $(“#表单id”).serialize()- 可以将表单数据自动拼接成key=value的结构提交给服务器,一般提交的是普通的空间数据(比如:text\password\radio\checkbox等)
 
- new FormData($(“#表单id”)[index]) - FormData类,将表单中数据保持原有结构进行数据的发送
 
- ajax默认处理数据时按照字符串的形式进行处理,以及默认采用字符串的形式提交数据,关闭这两个默认功能 - ```javascript
 processData: false //处理数据的形式,false为关闭以字符串的形式处理数据
 contentType: false // 关闭默认的数据提交格式1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 ```javascript
 <script>
 $("#btn-change-avatar").click(function (){
 $.ajax({
 url: "/user/alert_avatar"
 ,type: "POST"
 ,data: new FormData($("#form-horizontal")[0])
 ,processData: false //处理数据的形式,false为关闭以字符串的形式处理数据
 ,contentType: false // 关闭默认的数据提交格式
 ,dataType: "JSON"
 ,success: function (data){
 if(data.state == 200){
 //图像显示在页面
 //attr(key,val) 给标签对应属性设置对应值
 $("#img-avatar").attr("src",data.data);
 alert("图像修改成功");
 }else{
 alert("图像上传失败 "+data.message);
 }
 }
 ,error:function (xmh){
 alert("图像上传发生未知异常"+xmh.status);
 }
 });
 });
 </script>
 
- ```javascript
页面跳转图像消失解决办法
从其他页面再次回到当前页面或者登陆时显示图像
- 图像上传成功后,可以将图像路径保存在cookie对象,然后每次检测用户打开上传图像页面,在该页面中通过 - $(document).ready()方法自动检测读取cookie中图像并设置到image的src属性
- 此逻辑应该写在登陆页面 - 前端query中cookie的使用 - 1 
 2
 3
 4
 5- //1.导入cookie js文件 
 <script src="../bootstrap3/js/jquery.cookie.js" type="text/javascript" charset="utf-8"></script>
 //2.调用cookie方法
 //三个参数,key,avlue为键值对,time为cookie的存活时间,单位为天
 $.cookie(key,value,time);
- login.html页面新增逻辑 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25- <script> 
 $("#btn-login").click(function (){
 $.ajax({
 url: "/user/login"
 ,type: "POST"
 ,data: $("#form-login").serialize()
 ,dataType: "JSON"
 ,success: function (data){
 if(data.state == 200){
 alert("登录成功");
 //图像路径设置到cookie对象
 $.cookie("avatar",data.data.avatar, {expires:1});
 //跳转到对应页面
 //相对路径指定对应页面位置
 location.href="index.html"
 }else{
 alert("登陆失败 "+data.message);
 }
 }
 ,error:function (xmh){
 alert("登陆失败"+xmh.status);
 }
 });
 });
 </script>
- upload.html里面检测加载cookie的逻辑代码 - 1 
 2
 3
 4
 5
 6- $(document).ready(function () { 
 //获取cookie数据
 let avatar = $.cookie("avatar");
 alert(avatar);
 $("#img-avatar").attr("src",avatar);
 })
- 重新上传图像,需要覆盖原始cookie里的对象 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25- $("#btn-change-avatar").click(function (){ 
 $.ajax({
 url: "/user/alert_avatar"
 ,type: "POST"
 ,data: new FormData($("#form-horizontal")[0])
 ,processData: false //处理数据的形式,false为关闭以字符串的形式处理数据
 ,contentType: false // 关闭默认的数据提交格式
 ,dataType: "JSON"
 ,success: function (data){
 if(data.state == 200){
 //图像显示在页面
 //attr(key,val) 给标签对应属性设置对应值
 $("#img-avatar").attr("src",data.data);
 //覆盖原来的cookie
 $.cookie("avatar",data.data, {expires:1});
 alert("图像修改成功");
 }else{
 alert("图像上传失败 "+data.message);
 }
 }
 ,error:function (xmh){
 alert("图像上传发生未知异常"+xmh.status);
 }
 });
 });
 





