[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-public-QFFAqZh1":3,"public-project-articles-QFFAqZh1":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},778,"QFFAqZh1",49,"10. Springboot3+vue3实现文件上传和下载","## 文件下载 \n\n```java\n\u002F**\n * 文件下载\n * 下载路径：\"http:\u002F\u002Flocalhost:9999\u002Ffiles\u002Fdownload\u002F404.jpg\"\n *\u002F\n@GetMapping(\"\u002Fdownload\u002F{fileName}\")\npublic void download(@PathVariable String fileName, HttpServletResponse response) throws Exception {\n    \u002F\u002F 找到文件的位置\n    String filePath = System.getProperty(\"user.dir\") + \"\u002Ffiles\u002F\";  \u002F\u002F 获取到当前项目的根路径（code2025的绝对路径 D:\\项目实战\\小白做毕设\\代码\\code2025）\n    String realPath = filePath + fileName;  \u002F\u002F  D:\\项目实战\\小白做毕设\\代码\\code2025\\files\\404.jpg\n    boolean exist = FileUtil.exist(realPath);\n    if (!exist) {\n        throw new CustomerException(\"文件不存在\");\n    }\n    \u002F\u002F 读取文件的字节流\n    byte[] bytes = FileUtil.readBytes(realPath);\n    ServletOutputStream os = response.getOutputStream();\n    \u002F\u002F 输出流对象把文件写出到客户端\n    os.write(bytes);\n    os.flush();\n    os.close();\n}\n```\n\n\n\n以附件的形式下载文件（可忽略）\n\n```java\nresponse.addHeader(\"Content-Disposition\", \"attachment;filename=\" + URLEncoder.encode(fileName, StandardCharsets.UTF_8));\nresponse.setContentType(\"application\u002Foctet-stream\");\n```\n\n\n\n接口放行，不鉴权 \n\n\u003Cfont style=\"color:#bcbec4;background-color:#1e1f22;\">\"\u002Ffiles\u002Fdownload\u002F**\"\u003C\u002Ffont>\n\n![](https:\u002F\u002Fcdn.nlark.com\u002Fyuque\u002F0\u002F2025\u002Fpng\u002F751015\u002F1740374523904-ba7d0e3c-b7e9-4be4-b16d-01038a55ca86.png)\n\n## 文件上传\n\n```java\n\u002F**\n * 文件上传\n *\u002F\n@PostMapping(\"\u002Fupload\")\npublic Result upload(@RequestParam(\"file\") MultipartFile file) throws Exception {\n    \u002F\u002F 找到文件的位置\n    String filePath = System.getProperty(\"user.dir\") + \"\u002Ffiles\u002F\";\n    if (!FileUtil.isDirectory(filePath)) {\n        FileUtil.mkdir(filePath);\n    }\n    byte[] bytes = file.getBytes();\n    String fileName = System.currentTimeMillis() + \"_\" + file.getOriginalFilename();  \u002F\u002F 文件的原始名称\n    \u002F\u002F 写入文件\n    FileUtil.writeBytes(bytes, filePath + fileName);\n    String url = \"http:\u002F\u002Flocalhost:9999\u002Ffiles\u002Fdownload\u002F\" + fileName;\n    return Result.success(url);\n}\n```\n\n\n\n使用 apipost 测试文件上传\n\n[https:\u002F\u002Fwww.apipost.cn\u002F](https:\u002F\u002Fwww.apipost.cn\u002F)\n\n![](https:\u002F\u002Fcdn.nlark.com\u002Fyuque\u002F0\u002F2025\u002Fpng\u002F751015\u002F1740375944100-e6e2e953-c021-494c-bbf4-3be90c5f4584.png)\n\n\n\n## 在数据库表  admin 和 user 里面加上 avatar 字段\n\n![](https:\u002F\u002Fcdn.nlark.com\u002Fyuque\u002F0\u002F2025\u002Fpng\u002F751015\u002F1740376187418-1bfca8dd-20fb-4f56-8955-e2dd59e7b872.png)\n\n\n\n注意在 Mapper.xml 里面加上  avatar 的 sql\n\n![](https:\u002F\u002Fcdn.nlark.com\u002Fyuque\u002F0\u002F2025\u002Fpng\u002F751015\u002F1740376261981-f8f0a457-4b51-4505-bd24-ca68822c535b.png)\n\n## 前端对接文件上传和下载\n\n文件上传到数据库存储的是一串 url 链接的字符串\n\n![](https:\u002F\u002Fcdn.nlark.com\u002Fyuque\u002F0\u002F2025\u002Fpng\u002F751015\u002F1740376631354-3aaed0da-963e-4e2a-8dcf-537a95fe4616.png)\n\n### 表单上传\n\n```vue\n\u003Cel-form-item prop=\"avatar\" label=\"头像\">\n  \u003Cel-upload\n    action=\"http:\u002F\u002Flocalhost:9999\u002Ffiles\u002Fupload\"\n    :headers=\"{ token: data.user.token }\"\n    :on-success=\"handleFileSuccess\"\n    list-type=\"picture\"\n  >\n    \u003Cel-button type=\"primary\">上传头像\u003C\u002Fel-button>\n  \u003C\u002Fel-upload>\n\u003C\u002Fel-form-item>\n\nconst handleFileSuccess = (res) => {\n  data.form.avatar = res.data\n}\n```\n\n### 表格显示图片\n\n```vue\n\u003Cel-table-column label=\"头像\">\n  \u003Ctemplate #default=\"scope\">\n    \u003Cel-image v-if=\"scope.row.avatar\" :src=\"scope.row.avatar\" :preview-src-list=\"[scope.row.avatar]\" :preview-teleported=\"true\"\n              style=\"width: 40px; height: 40px; border-radius: 50%; display: block\" \u002F>\n  \u003C\u002Ftemplate>\n\u003C\u002Fel-table-column>\n```\n\n\n\n图片预览效果不理想，加上属性    :preview-teleported=\"true\"\n\n![](https:\u002F\u002Fcdn.nlark.com\u002Fyuque\u002F0\u002F2025\u002Fpng\u002F751015\u002F1740376898938-2452a6d1-5c84-44e5-b58a-e11129e095e5.png)\n\n\n\n","coding",1,6171,1524,"2025-02-24 14:16:27","2026-05-03 22:49:02","带小白做毕设2025系列课程","graduation-project-2025",{"project":18,"items":19},{"id":6,"title":15,"slug":16},[20,28,35,42,49,56,63,70,77,84,91,92,99,106,113,120,127,134,141,148,155],{"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},766,"XmlcAcY0","00. 带小白做毕设2025课程介绍",19012,1512,"2025-02-22 15:29:01","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},767,"nmjXCdVH","01. 前端Vue3 框架的快速搭建以及项目工程的讲解",15797,1513,"2025-02-13 17:13:40",{"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},768,"pMdPrVeH","02. 使用Vue3集成Element-Plus快速搭建一个管理系统的页面框架",15959,1514,"2025-02-14 11:25:07",{"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},771,"8PikYMQU","03. Springboot3框架的快速搭建以及项目工程的讲解",12768,1517,"2025-02-21 17:21:51",{"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},772,"Q1TCG9Jj","04. Springboot3整合MyBatis实现数据库操作",11144,1518,"2025-03-07 15:50:30",{"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},773,"De7YPnEc","05. Springboot3+vue3实现增删改查、分页查询、批量删除（上）",10827,1519,"2025-02-22 15:09:19",{"id":64,"uuid":65,"project_id":6,"title":66,"type":9,"status":10,"public_enabled":10,"views":67,"sort":68,"created_at":69,"updated_at":14,"project_title":15,"project_slug":16},774,"YKEHfsPd","06. Springboot3+vue3实现增删改查、分页查询、批量删除（下）",7760,1520,"2025-02-22 22:00:02",{"id":71,"uuid":72,"project_id":6,"title":73,"type":9,"status":10,"public_enabled":10,"views":74,"sort":75,"created_at":76,"updated_at":14,"project_title":15,"project_slug":16},775,"sNDKpWVJ","07. Springboot3+Vue3实现excel批量导入导出",6552,1521,"2025-02-23 10:49:24",{"id":78,"uuid":79,"project_id":6,"title":80,"type":9,"status":10,"public_enabled":10,"views":81,"sort":82,"created_at":83,"updated_at":14,"project_title":15,"project_slug":16},776,"1uMP9O6C","08. Springboot3+vue3实现登录注册功能",7964,1522,"2025-02-23 18:14:13",{"id":85,"uuid":86,"project_id":6,"title":87,"type":9,"status":10,"public_enabled":10,"views":88,"sort":89,"created_at":90,"updated_at":14,"project_title":15,"project_slug":16},777,"WahvQp1v","09. Springboot3+vue3实现JWT登录鉴权",7151,1523,"2025-02-23 21:58: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":93,"uuid":94,"project_id":6,"title":95,"type":9,"status":10,"public_enabled":10,"views":96,"sort":97,"created_at":98,"updated_at":14,"project_title":15,"project_slug":16},1278,"S2eL2g5L","11. Springboot3+vue3实现个人中心、修改密码",5945,1525,"2025-02-24 18:10:59",{"id":100,"uuid":101,"project_id":6,"title":102,"type":9,"status":10,"public_enabled":10,"views":103,"sort":104,"created_at":105,"updated_at":14,"project_title":15,"project_slug":16},1279,"LkN8Mmsn","12. Springboot3+Vue3实现系统公告功能",4967,1526,"2025-02-25 11:50:13",{"id":107,"uuid":108,"project_id":6,"title":109,"type":9,"status":10,"public_enabled":10,"views":110,"sort":111,"created_at":112,"updated_at":14,"project_title":15,"project_slug":16},1280,"i7wziuEN","13. Springboot3+Vue3实现角色权限控制",4446,1527,"2025-02-25 11:51:38",{"id":114,"uuid":115,"project_id":6,"title":116,"type":9,"status":10,"public_enabled":10,"views":117,"sort":118,"created_at":119,"updated_at":14,"project_title":15,"project_slug":16},1281,"pGwiTCRn","14. Springboot3+Vue3实现富文本编辑器功能",4578,1528,"2025-02-26 16:04:58",{"id":121,"uuid":122,"project_id":6,"title":123,"type":9,"status":10,"public_enabled":10,"views":124,"sort":125,"created_at":126,"updated_at":14,"project_title":15,"project_slug":16},1282,"tZ8iDql5","15. Springboot3+Vue3实现模块之间的关联",4454,1529,"2025-02-26 18:28:55",{"id":128,"uuid":129,"project_id":6,"title":130,"type":9,"status":10,"public_enabled":10,"views":131,"sort":132,"created_at":133,"updated_at":14,"project_title":15,"project_slug":16},1283,"gb01JPC2","16. Springboot3+Vue3实现echarts数据统计",4307,1530,"2025-03-03 16:58:21",{"id":135,"uuid":136,"project_id":6,"title":137,"type":9,"status":10,"public_enabled":10,"views":138,"sort":139,"created_at":140,"updated_at":14,"project_title":15,"project_slug":16},1284,"59bDkSFf","17. Springboot3+Vue3实现提交审核业务功能",3793,1531,"2025-03-04 11:58:16",{"id":142,"uuid":143,"project_id":6,"title":144,"type":9,"status":10,"public_enabled":10,"views":145,"sort":146,"created_at":147,"updated_at":14,"project_title":15,"project_slug":16},1285,"gApyb58X","18. Springboot3+Vue3实现预约审核业务功能",3332,1532,"2025-03-05 20:07:24",{"id":149,"uuid":150,"project_id":6,"title":151,"type":9,"status":10,"public_enabled":10,"views":152,"sort":153,"created_at":154,"updated_at":14,"project_title":15,"project_slug":16},1286,"XfpY5re0","19. Springboot3+Vue3实现前台首页的设计",3508,1533,"2025-03-05 20:08:12",{"id":156,"uuid":157,"project_id":6,"title":158,"type":9,"status":10,"public_enabled":10,"views":159,"sort":160,"created_at":161,"updated_at":14,"project_title":15,"project_slug":16},1287,"BnSPRBOc","20. Springboot3+Vue3实现前台轮播图和详情页的设计",4062,1534,"2025-03-17 17:13:36"]