赞
踩
我做的毕设里面的用户页面需要上传头像,现在把详细的业务流程和实现写在这里,供大家参考一下。
有一些细节的前端问题自己解决叭,不然太多了。
先展示一下我的前端页面。
因为我使用jQuery写的js,页面用了bootstrap,也用了它的弹窗插件bootbox,模板引擎用的是thymeleaf,是使用axios做异步的…
设置的全局变量。
var file; // 定义一个全局变量,为一个文本选择器。
var chooseImage; // 用于上传的文件
file = $('<input type="file" />'); // 这样file就是jquery创建的一个文本选择器,但是因为我们并没有把它加载到页面上,所以是不可见的。
// button的单击事件 $('#chooseImg').click(function(){ // 启动文件选择 file.click(); }); // 选择好文件后,获取选择的内容 file.change(function(e){ var select_file = file[0].files[0]; // 校验文件名称 var file_path = file.val(); var extStart = file_path.lastIndexOf("."); // 按.分隔文件名称 var ext = file_path.substring(extStart, file_path.length).toUpperCase(); // 取出后缀并转为大写 if (ext != ".BMP" && ext != ".PNG" && ext != ".JPG" && ext != ".JPEG") { bootbox.alert({ size: "small", title: "提示", message: "图片仅限于bmp,png,jpg,jpeg的格式!", buttons: { ok: { label: '确认', className: 'btn-primary' } }, callback: function(){ /* your callback code */ } }) return false; } // 校验文件大小 if (select_file.size > 1048576) { bootbox.alert({ size: "small", title: "提示", message: "图片大小不能超过1M!!", buttons: { ok: { label: '确认', className: 'btn-primary' } }, callback: function(){ /* your callback code */ } }) return false; } chooseImage = select_file; // 赋值给全局变量 --> 用来做上传的操作 // 展示到页面 var reader = new FileReader();// 读取文件URL reader.readAsDataURL(chooseImage); reader.onload = function() { // 读取的URL结果:this.result $("#re_headImg").attr("src", this.result).show(); } $("#uploadImg").removeClass("update-head-msg-bt-dis"); $("#uploadImg").removeAttr("disabled"); $("#uploadImg").attr("title","选择提交即可上传该图片文件作为头像."); }); });
这段代码总体就是三步走,因为我是代码中生成input,它的type为file,所以页面是无法显示,用一个全局变量来接收,做上传使用 -> chooseImage (就是它),第一步就是校验它的文件格式,用substring分割字符换,第二步就是校验文件大小,第三步就是回显到页面,具体的业务根据自己的来设计。
得到的效果如下所示。
我在上面对提交按钮设置了disabled,在选择完文件后removeAttr删除它的属性,接下来对form表单进行异步提交, 设置了 event.preventDefault(); 使事件无效,单纯用来异步。
// 头像上传提交事件 $("#uploadHeadImg_form").submit(function () { event.preventDefault(); var formData = new FormData(); // 要提交的内容封装进formdata formData.append("file", chooseImage); formData.append('userId', [[${userInfo.id}]]) axios({ method: 'post', url: '/uploadImage/uploadHeadImg', data: formData }) .then(function (response) { if (response.data.state == 0) { // 说明上传失败 bootbox.alert({ size: "small", title: "修改提示", message: "上传头像失败", buttons: { ok: { label: '确认', className: 'btn-primary' } }, callback: function(){ /* your callback code */ } }) } else if (response.data.state == 1) { // 说明添加成功 // 更新页面数据 var reader = new FileReader();// 读取文件URL reader.readAsDataURL(chooseImage); reader.onload = function() { // 读取的URL结果:this.result $("#avatar_img").attr("src", this.result).show(); // 异步更新页面上的头像图片 $("#local_headImg").attr("src", this.result).show(); // 异步更新页面上的头像图片 $("#uploadImg").addClass("update-head-msg-bt-dis"); $("#uploadImg").attr("disabled","disabled"); $("#uploadImg").attr("title","请先选择要上传的图片文件."); } bootbox.alert({ size: "small", title: "修改提示", message: "上传头像成功", buttons: { ok: { label: '确认', className: 'btn-primary' } }, callback: function(){ /* your callback code */ } }) } }) .catch(function (error) { console.log(error); }); });
这段代码就是做异步提交工作,如果成功则更改页面属性,失败则弹窗报错。
<!--thymeleaf模板引擎-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--fileupload-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3</version>
</dependency>
controller接收参数,文件和要更改头像用户的id,使用MultipartFile接收文件。逻辑比较简单,大家看一下就行了。
我将文件路径都写在全局配置文件application.properties
#文件上传地址
file.upload.path.realPath=D://idea_springBoot_place/second-hand-website/src/main/resources/static/upload/
file.upload.path.relativePath=/upload/**
在通过@configurationProperties来通过配置文件来解耦。
@Component @ConfigurationProperties(prefix = "file.upload.path") public class MyUploadPathProperties { /** * 文件保存路径 */ private String realPath; /** * 文件保存相对路径 */ private String relativePath; public String getRealPath() { return realPath; } public void setRealPath(String realPath) { this.realPath = realPath; } public String getRelativePath() { return relativePath; } public void setRelativePath(String relativePath) { this.relativePath = relativePath; } }
这里是实现文件上传和删除的主要逻辑代码。
这是controller的逻辑,就是通过File类来保存和删除。
@Controller @RequestMapping("/uploadImage") public class UploadImageController { @Autowired MyUploadPathProperties myUploadPathProperties; @Autowired UserService userService; @ResponseBody @PostMapping("/uploadHeadImg") public Object uploadHeadImg (MultipartFile file, Integer userId) { String oldName = file.getOriginalFilename(); // 获取上传文件名 // path = D://idea_springBoot_place/second-hand-website/src/main/resources/static/upload/headImg/ String path = myUploadPathProperties.getRealPath() + "headImg/"; // 定义上传文件路径 String fileName = changeName(oldName); // 改名 String rappendix = "/upload/headImg/" + fileName; // 文件相对路径 // File.separator + fileName = path + fileName; // 文件绝对路径 File file1 = new File(fileName); // 新建文件 if (!file1.exists()) { //先得到文件的上级目录,并创建上级目录,在创建文件 file1.getParentFile().mkdir(); try { //创建文件 file1.createNewFile(); } catch (IOException e) { throw new UpLoadException("创建文件失败!"); } } // 写入文件 try { file.transferTo(file1); } catch (IOException e) { throw new UpLoadException("写入文件失败!"); } System.out.println(rappendix); System.out.println(file1); //------------------------------- // 删除原文件 String oldPath = userService.findById(userId).getHeadImg(); String oldFileName = myUploadPathProperties.getRealPath() + oldPath.substring(8); // 从 /upload/ 后面开始拼接 if (!oldPath.equals("/upload/headImg/default.jpg")) { // 默认头像不删除 if (!delete(oldFileName)) { throw new UpLoadException("删除原文件失败"); } } // ------------------------------ // 操作数据库修改 userService.updateHeadImg(userId, rappendix); return new JsonResult(rappendix); } /** * 改名 * @param oldName * @return */ public static String changeName(String oldName){ Random r = new Random(); Date d = new Date(); String newName = oldName.substring(oldName.indexOf('.')); newName = r.nextInt(99999999) + d.getTime() + newName; System.out.println(newName); return newName; } /** * 删除文件 * @param filePath * @return */ public static Boolean delete(String filePath) { File file = new File(filePath); if (file.exists()) { file.delete(); System.out.println("===========删除成功================="); return true; } else { System.out.println("===============删除失败=============="); return false; } } }
在service层就是修改user表中的img路径。
得到效果如下所示
如果有什么问题请给我留言吧,一起互相进步互相学习。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。