[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-public-7xzyVD06":3,"public-project-articles-7xzyVD06":17},{"id":4,"uuid":5,"project_id":6,"title":7,"content":8,"type":9,"status":10,"public_enabled":10,"views":11,"sort":12,"created_at":13,"updated_at":14,"project_title":15,"project_slug":16},46,"7xzyVD06",39,"13. SpringBoot+Vue实现单文件、多文件上传和下载","\n## 加一个全局的异常处理\n\n![image.png](https:\u002F\u002Fcdn.nlark.com\u002Fyuque\u002F0\u002F2023\u002Fpng\u002F751015\u002F1693142857806-95e147a7-3a9f-465c-b6e8-3164dcc07ff5.png#averageHue=%238e8753&clientId=u355a6559-82c8-4&from=paste&height=405&id=udee2de99&originHeight=506&originWidth=1461&originalType=binary&ratio=1.25&rotation=0&showTitle=false&size=93393&status=done&style=none&taskId=u26b63130-ecba-4743-94e3-cab0c80142b&title=&width=1168.8)\n\n```java\n@ExceptionHandler(Exception.class)\n@ResponseBody\npublic Result globalException(Exception e) {\n    e.printStackTrace();\n    return Result.error(\"500\", \"系统错误\");\n}\n```\n\n## 单文件上传\n\npostman 请求\n![image.png](https:\u002F\u002Fcdn.nlark.com\u002Fyuque\u002F0\u002F2023\u002Fpng\u002F751015\u002F1693143162599-df755b89-8696-42ee-8ea6-dc3aea4efebd.png#averageHue=%23fdfbfb&clientId=u355a6559-82c8-4&from=paste&height=577&id=ub028263f&originHeight=721&originWidth=1795&originalType=binary&ratio=1.25&rotation=0&showTitle=false&size=79755&status=done&style=none&taskId=u906db263-f2d8-4087-ad9a-09644e0d245&title=&width=1436)\n文件上传代码：\njava\n\n```java\nimport cn.hutool.core.io.FileUtil;\nimport com.example.springboot.common.AuthAccess;\nimport com.example.springboot.common.Result;\nimport org.springframework.beans.factory.annotation.Value;\nimport org.springframework.web.bind.annotation.*;\nimport org.springframework.web.multipart.MultipartFile;\n\nimport javax.servlet.ServletOutputStream;\nimport javax.servlet.http.HttpServletResponse;\nimport java.io.File;\nimport java.io.IOException;\nimport java.net.URLEncoder;\n\n@Value(\"${ip:localhost}\")\nString ip;\n\n@Value(\"${server.port}\")\nString port;\n\nprivate static final String ROOT_PATH =  System.getProperty(\"user.dir\") + File.separator + \"files\";  \u002F\u002F D:\\B站\\小白做毕设2024\\代码\\小白做毕设2024\\files\n\n@PostMapping(\"\u002Fupload\")\npublic Result upload(MultipartFile file) throws IOException {\n    String originalFilename = file.getOriginalFilename();  \u002F\u002F 文件的原始名称\n    \u002F\u002F aaa.png\n    String mainName = FileUtil.mainName(originalFilename);  \u002F\u002F aaa\n    String extName = FileUtil.extName(originalFilename);\u002F\u002F png\n    if (!FileUtil.exist(ROOT_PATH)) {\n        FileUtil.mkdir(ROOT_PATH);  \u002F\u002F 如果当前文件的父级目录不存在，就创建\n    }\n    if (FileUtil.exist(ROOT_PATH + File.separator + originalFilename)) {  \u002F\u002F 如果当前上传的文件已经存在了，那么这个时候我就要重名一个文件名称\n        originalFilename = System.currentTimeMillis() + \"_\" + mainName + \".\" + extName;\n    }\n    File saveFile = new File(ROOT_PATH + File.separator + originalFilename);\n    file.transferTo(saveFile);  \u002F\u002F 存储文件到本地的磁盘里面去\n    String url = \"http:\u002F\u002F\" + ip + \":\" + port + \"\u002Ffile\u002Fdownload\u002F\" + originalFilename;\n    return Result.success(url);  \u002F\u002F返回文件的链接，这个链接就是文件的下载地址，这个下载地址就是我的后台提供出来的\n}\n```\n\nvue\n获取用户信息：\n\n```java\nuser: JSON.parse(localStorage.getItem('honey-user') || '{}'),\n```\n\n文件上传组件代码\n\n```vue\n\u003Cel-upload\n    action=\"http:\u002F\u002Flocalhost:9090\u002Ffile\u002Fupload\"\n    :headers=\"{token: user.token}\"\n    :on-success=\"handleFileUpload\"\n>\n  \u003Cel-button size=\"mini\" type=\"primary\">单文件上传\u003C\u002Fel-button>\n\u003C\u002Fel-upload>\n```\n\n文件上传回调钩子\n\n```java\nhandleFileUpload(response, file, fileList) {\n\tconsole.log(response, file, fileList)\n},\n```\n\n文件存储到后台，发送更新的请求\n\n```vue\nhandleTableFileUpload(row, file, fileList) {\n  console.log(row, file, fileList)\n  row.avatar = file.response.data\n  \u002F\u002F this.$set(row, 'avatar', file.response.data)\n  console.log(row)\n  \u002F\u002F 触发更新就可以了\n  request.put('\u002Fuser\u002Fupdate', row).then(res => {\n    if (res.code === '200') {\n      this.$message.success('上传成功')\n    } else {\n      this.$message.error(res.msg)\n    }\n  })\n},\n```\n\n## 多文件上传\n\nvue\n\n```vue\n\u003Cel-upload\n      action=\"http:\u002F\u002Flocalhost:9090\u002Ffile\u002Fupload\"\n      :headers=\"{token: user.token}\"\n      :on-success=\"handleMultipleFileUpload\"\n      multiple\n  >\n    \u003Cel-button size=\"mini\" type=\"success\">多文件上传\u003C\u002Fel-button>\n  \u003C\u002Fel-upload>\n  \u003Cel-button type=\"primary\" style=\"margin:  10px 0\" @click=\"showUrls\">显示上传的链接\u003C\u002Fel-button>\n\n\u003C\u002Fdiv>\n```\n\n```vue\nhandleMultipleFileUpload(response, file, fileList) {\n  this.urls = fileList.map(v => v.response?.data)\n},\n```\n\n## 文件下载\n\nresponse.addHeader(\"Content-Disposition\", \"attachment;filename=\" + URLEncoder.encode(fileFullName, \"UTF-8\")); \u002F\u002F 附件下载\n\n```java\n@AuthAccess\n@GetMapping(\"\u002Fdownload\u002F{fileName}\")\npublic void download(@PathVariable String fileName, HttpServletResponse response) throws IOException {\n    response.addHeader(\"Content-Disposition\", \"attachment;filename=\" + URLEncoder.encode(fileFullName, \"UTF-8\"));  \u002F\u002F 附件下载\n    String filePath = ROOT_PATH  + File.separator + fileName;\n    if (!FileUtil.exist(filePath)) {\n        return;\n    }\n    byte[] bytes = FileUtil.readBytes(filePath);\n    ServletOutputStream outputStream = response.getOutputStream();\n    outputStream.write(bytes);  \u002F\u002F 数组是一个字节数组，也就是文件的字节流数组\n    outputStream.flush();\n    outputStream.close();\n}\n```\n\n## 文件预览\n\n根据文件的类型区分的，一般是图片和 pdf 可以预览\nresponse.addHeader(\"Content-Disposition\", \"inline;filename=\" + URLEncoder.encode(fileFullName, \"UTF-8\")); \u002F\u002F 预览\n\n```java\n@AuthAccess\n@GetMapping(\"\u002Fdownload\u002F{fileName}\")\npublic void download(@PathVariable String fileName, HttpServletResponse response) throws IOException {\n    response.addHeader(\"Content-Disposition\", \"inline;filename=\" + URLEncoder.encode(fileFullName, \"UTF-8\"));  \u002F\u002F 预览\n    String filePath = ROOT_PATH  + File.separator + fileName;\n    if (!FileUtil.exist(filePath)) {\n        return;\n    }\n    byte[] bytes = FileUtil.readBytes(filePath);\n    ServletOutputStream outputStream = response.getOutputStream();\n    outputStream.write(bytes);  \u002F\u002F 数组是一个字节数组，也就是文件的字节流数组\n    outputStream.flush();\n    outputStream.close();\n}\n```\n","coding",1,2784,68,"2024-04-16 02:32:52","2026-05-03 22:49:02","【青哥带小白做毕设2024】完整教程资料汇总","qingge-graduation-project-2024",{"project":18,"items":19},{"id":6,"title":15,"slug":16},[20,28,35,42,49,56,63,69,76,83,90,97,104,111,112,119,126,133,140,147,154,161,168],{"id":21,"uuid":22,"project_id":6,"title":23,"type":9,"status":10,"public_enabled":10,"views":24,"sort":25,"created_at":26,"updated_at":27,"project_title":15,"project_slug":16},33,"R1oMCsCX","00. 从0开始带小白做SpringBoot+Vue+uniapp微信小程序实战项目",12130,55,"2025-04-08 11:28:17","2026-05-07 15:33:28.189425+00",{"id":29,"uuid":30,"project_id":6,"title":31,"type":9,"status":10,"public_enabled":10,"views":32,"sort":33,"created_at":34,"updated_at":14,"project_title":15,"project_slug":16},34,"s3u3u8W7","01. 网页布局技巧",3326,56,"2025-04-08 11:28:13",{"id":36,"uuid":37,"project_id":6,"title":38,"type":9,"status":10,"public_enabled":10,"views":39,"sort":40,"created_at":41,"updated_at":14,"project_title":15,"project_slug":16},35,"21zUHQYS","02. JavaScript入门",2017,57,"2025-04-08 11:27:55",{"id":43,"uuid":44,"project_id":6,"title":45,"type":9,"status":10,"public_enabled":10,"views":46,"sort":47,"created_at":48,"updated_at":14,"project_title":15,"project_slug":16},36,"4XVgY9Ti","03. Vue脚手架搭建",3719,58,"2025-04-08 11:27:46",{"id":50,"uuid":51,"project_id":6,"title":52,"type":9,"status":10,"public_enabled":10,"views":53,"sort":54,"created_at":55,"updated_at":14,"project_title":15,"project_slug":16},37,"S8vLLLvk","04. Git速成，推送代码到云端",1585,59,"2025-04-08 11:27:41",{"id":57,"uuid":58,"project_id":6,"title":59,"type":9,"status":10,"public_enabled":10,"views":60,"sort":61,"created_at":62,"updated_at":14,"project_title":15,"project_slug":16},38,"9EbwnGDp","05. 网页布局神器ElementUI速成",2670,60,"2025-04-08 11:27:37",{"id":6,"uuid":64,"project_id":6,"title":65,"type":9,"status":10,"public_enabled":10,"views":66,"sort":67,"created_at":68,"updated_at":14,"project_title":15,"project_slug":16},"tmzahWer","06. Vue管理系统速成",3744,61,"2025-04-08 11:27:32",{"id":70,"uuid":71,"project_id":6,"title":72,"type":9,"status":10,"public_enabled":10,"views":73,"sort":74,"created_at":75,"updated_at":14,"project_title":15,"project_slug":16},40,"2agqAUQK","07. SpringBoot速成",3654,62,"2025-04-08 11:27:27",{"id":77,"uuid":78,"project_id":6,"title":79,"type":9,"status":10,"public_enabled":10,"views":80,"sort":81,"created_at":82,"updated_at":14,"project_title":15,"project_slug":16},41,"SXPAzgy7","08. Http扫盲，让小白也能听懂",2337,63,"2025-04-08 11:27:20",{"id":84,"uuid":85,"project_id":6,"title":86,"type":9,"status":10,"public_enabled":10,"views":87,"sort":88,"created_at":89,"updated_at":14,"project_title":15,"project_slug":16},42,"ostBIxAV","09. SpringBoot集成Mybatis实现增删改查",4190,64,"2025-04-08 11:27:13",{"id":91,"uuid":92,"project_id":6,"title":93,"type":9,"status":10,"public_enabled":10,"views":94,"sort":95,"created_at":96,"updated_at":14,"project_title":15,"project_slug":16},43,"6Sv7afpa","10. Vue封装前后端数据交互工具",3716,65,"2024-04-16 02:33:13",{"id":98,"uuid":99,"project_id":6,"title":100,"type":9,"status":10,"public_enabled":10,"views":101,"sort":102,"created_at":103,"updated_at":14,"project_title":15,"project_slug":16},44,"d53BPIQs","11. Vue登录（含验证码）、注册页面开发",4867,66,"2024-04-16 02:33:08",{"id":105,"uuid":106,"project_id":6,"title":107,"type":9,"status":10,"public_enabled":10,"views":108,"sort":109,"created_at":110,"updated_at":14,"project_title":15,"project_slug":16},45,"m033ng06","12. SpringBoot集成JWT token实现权限验证",3243,67,"2024-04-16 02:33:00",{"id":4,"uuid":5,"project_id":6,"title":7,"type":9,"status":10,"public_enabled":10,"views":11,"sort":12,"created_at":13,"updated_at":14,"project_title":15,"project_slug":16},{"id":113,"uuid":114,"project_id":6,"title":115,"type":9,"status":10,"public_enabled":10,"views":116,"sort":117,"created_at":118,"updated_at":14,"project_title":15,"project_slug":16},47,"BdOLUenp","14. 多角色登录（Vue-Router路由守卫）",2318,69,"2024-04-16 02:32:39",{"id":120,"uuid":121,"project_id":6,"title":122,"type":9,"status":10,"public_enabled":10,"views":123,"sort":124,"created_at":125,"updated_at":14,"project_title":15,"project_slug":16},48,"2Wkx3igg","15. Vue个人信息修改、修改密码、重置密码",2092,70,"2024-04-16 02:32:33",{"id":127,"uuid":128,"project_id":6,"title":129,"type":9,"status":10,"public_enabled":10,"views":130,"sort":131,"created_at":132,"updated_at":14,"project_title":15,"project_slug":16},49,"BDvVa4By","16. SpringBoot+Vue管理系统实现增删改查",2598,71,"2024-04-16 02:32:29",{"id":134,"uuid":135,"project_id":6,"title":136,"type":9,"status":10,"public_enabled":10,"views":137,"sort":138,"created_at":139,"updated_at":14,"project_title":15,"project_slug":16},50,"FJVl0rCu","17. SpringBoot+Vue实现数据的批量导入和导出",1684,72,"2024-04-16 02:32:26",{"id":141,"uuid":142,"project_id":6,"title":143,"type":9,"status":10,"public_enabled":10,"views":144,"sort":145,"created_at":146,"updated_at":14,"project_title":15,"project_slug":16},51,"FvW9oHgj","18. SpringBoot+Vue项目部署上线",2845,73,"2024-04-16 02:32:22",{"id":148,"uuid":149,"project_id":6,"title":150,"type":9,"status":10,"public_enabled":10,"views":151,"sort":152,"created_at":153,"updated_at":14,"project_title":15,"project_slug":16},52,"xyqrxxiR","19. SpringBoot+Vue集成富文本编辑器",1499,74,"2024-04-16 02:32:18",{"id":155,"uuid":156,"project_id":6,"title":157,"type":9,"status":10,"public_enabled":10,"views":158,"sort":159,"created_at":160,"updated_at":14,"project_title":15,"project_slug":16},53,"XAaCXz8W","20. SpringBoot+Vue集成系统公告",1043,75,"2024-04-16 02:32:14",{"id":162,"uuid":163,"project_id":6,"title":164,"type":9,"status":10,"public_enabled":10,"views":165,"sort":166,"created_at":167,"updated_at":14,"project_title":15,"project_slug":16},54,"2havlmaC","21. SpringBoot+Vue集成AOP系统日志",1159,76,"2024-04-16 02:32:11",{"id":25,"uuid":169,"project_id":6,"title":170,"type":9,"status":10,"public_enabled":10,"views":171,"sort":172,"created_at":173,"updated_at":14,"project_title":15,"project_slug":16},"ObvLqJdX","22. SpringBoot+Vue实现Echarts数据报表（柱状图、饼图、折线图）",1688,99,"2024-04-16 02:30:25"]