当前位置:   article > 正文

vue+springboot实现文件上传_vue+springboot文件上传

vue+springboot文件上传

①后端springboot创建controller

FileController:

  1. package com.example.springboot.controller;
  2. import cn.hutool.core.io.FileUtil;
  3. import com.example.springboot.common.AuthAccess;
  4. import com.example.springboot.common.Result;
  5. import org.springframework.beans.factory.annotation.Value;
  6. import org.springframework.web.bind.annotation.*;
  7. import org.springframework.web.multipart.MultipartFile;
  8. import javax.servlet.ServletOutputStream;
  9. import javax.servlet.http.HttpServletResponse;
  10. import java.io.File;
  11. import java.io.IOException;
  12. import java.net.URLEncoder;
  13. @RestController
  14. @RequestMapping("/file")
  15. public class FileController {
  16. @Value("${ip:localhost}")
  17. String ip;
  18. @Value("${server.port}")
  19. String port;
  20. private static final String ROOT_PATH=System.getProperty("user.dir")+File.separator+"files";
  21. @PostMapping("/upload")
  22. public Result upload(MultipartFile file) throws IOException{
  23. String originFilename= file.getOriginalFilename();
  24. String mainName= FileUtil.mainName(originFilename);
  25. String extName=FileUtil.extName(originFilename);
  26. if(!FileUtil.exist(ROOT_PATH)){
  27. FileUtil.mkdir(ROOT_PATH);
  28. }
  29. if(FileUtil.exist(ROOT_PATH+File.separator+originFilename)){
  30. originFilename=System.currentTimeMillis()+"_"+mainName+"."+extName;
  31. }
  32. File saveFile=new File(ROOT_PATH+File.separator+originFilename);
  33. file.transferTo(saveFile);
  34. String url="http://"+ip+":"+port+"/file/download/"+originFilename;
  35. return Result.success(url);
  36. }
  37. @AuthAccess
  38. @GetMapping("/download/{filename}")
  39. public void download(@PathVariable String filename,HttpServletResponse response) throws IOException {
  40. // response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8")); // 附件下载
  41. response.addHeader("Content-Disposition", "inline;filename=" + URLEncoder.encode(filename, "UTF-8")); // 预览
  42. String filePath=ROOT_PATH+File.separator+filename;
  43. if(!FileUtil.exist(filePath)){
  44. return;
  45. }
  46. byte[] bytes=FileUtil.readBytes(filePath);
  47. ServletOutputStream outputStream=response.getOutputStream();
  48. outputStream.write(bytes);
  49. outputStream.flush();
  50. outputStream.close();
  51. }
  52. }

②修改yml文件:配置url和port等全局变量

application.yml:

  1. server:
  2. port: 9090
  3. spring:
  4. datasource:
  5. driver-class-name: com.mysql.cj.jdbc.Driver
  6. url: jdbc:mysql://${ip}:3306/honey2024?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8
  7. username: root
  8. password: 123456
  9. servlet:
  10. multipart:
  11. max-file-size: 20MB
  12. max-request-size: 20MB
  13. ip: localhost

③配置全局异常文件

GlobalExeception:

  1. package com.example.springboot.exception;
  2. import com.example.springboot.common.Result;
  3. import org.springframework.web.bind.annotation.ControllerAdvice;
  4. import org.springframework.web.bind.annotation.ExceptionHandler;
  5. import org.springframework.web.bind.annotation.ResponseBody;
  6. @ControllerAdvice
  7. public class GlobalExeception {
  8. @ExceptionHandler(ServiceException.class)
  9. @ResponseBody
  10. public Result serviceException(ServiceException e){
  11. return Result.error(e.getCode(),e.getMessage());
  12. }
  13. @ExceptionHandler(Exception.class)
  14. @ResponseBody
  15. public Result globalException(Exception e){
  16. e.printStackTrace();
  17. return Result.error("500","系统错误");
  18. }
  19. }

运行效果:

 

 访问一下这个url,发现可以预览:说明上传功能和预览,下载功能就完成了

至此后端的工作已经完成 

④前端修改编写页面

 

HomeView.vue:

  1. <template>
  2. <div>
  3. <el-container>
  4. <!-- 侧边栏 -->
  5. <el-aside :width="asideWidth" style="min-height: 100vh; background-color: #001529">
  6. <div style="height: 60px; color: white; display: flex; align-items: center; justify-content: center">
  7. <img src="@/assets/logo1.png" alt="" style="width: 40px; height: 40px">
  8. <span class="logo-title" v-show="!isCollapse">honey2024</span>
  9. </div>
  10. <el-menu :collapse="isCollapse" :collapse-transition="false" router background-color="#001529" text-color="rgba(255, 255, 255, 0.65)" active-text-color="#fff" style="border: none" :default-active="$route.path">
  11. <el-menu-item index="/">
  12. <i class="el-icon-menu"></i>
  13. <span slot="title">系统首页</span>
  14. </el-menu-item>
  15. <el-menu-item index="/1">
  16. <i class="el-icon-house"></i>
  17. <span slot="title">系统首页</span>
  18. </el-menu-item>
  19. <el-menu-item index="/2">
  20. <i class="el-icon-house"></i>
  21. <span slot="title">系统首页</span>
  22. </el-menu-item>
  23. <el-submenu index="3">
  24. <template slot="title">
  25. <i class="el-icon-menu"></i>
  26. <span>信息管理</span>
  27. </template>
  28. <el-menu-item>用户信息</el-menu-item>
  29. <el-menu-item>管理员信息</el-menu-item>
  30. <el-menu-item index="/">系统首页</el-menu-item>
  31. </el-submenu>
  32. </el-menu>
  33. </el-aside>
  34. <el-container>
  35. <!-- 头部区域-->
  36. <el-header>
  37. <i :class="collapseIcon" style="font-size: 26px" @click="handleCollapse"></i>
  38. <el-breadcrumb separator-class="el-icon-arrow-right" style="margin-left: 20px">
  39. <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
  40. <el-breadcrumb-item :to="{ path: '/user' }">用户管理</el-breadcrumb-item>
  41. </el-breadcrumb>
  42. <div style="flex: 1; width: 0; display: flex; align-items: center; justify-content: flex-end">
  43. <i class="el-icon-quanping" style="font-size: 26px" @click="handleFull"></i>
  44. <el-dropdown placement="bottom">
  45. <div style="display: flex; align-items: center; cursor: default">
  46. <img src="@/assets/logo1.png" alt="" style="width: 40px; height: 40px; margin: 0 5px">
  47. <span>管理员</span>
  48. </div>
  49. <el-dropdown-menu slot="dropdown">
  50. <el-dropdown-item>个人信息</el-dropdown-item>
  51. <el-dropdown-item>修改密码</el-dropdown-item>
  52. <el-dropdown-item @click.native="logout">退出登录</el-dropdown-item>
  53. </el-dropdown-menu>
  54. </el-dropdown>
  55. </div>
  56. </el-header>
  57. <!-- 主体区域-->
  58. <el-main>
  59. <div style="box-shadow: 0 0 10px rgba(0,0,0,.1); padding: 10px 20px; border-radius: 5px; margin-bottom: 10px">
  60. 早安,骚年,祝你开心每一天!
  61. </div>
  62. <div style="display: flex;">
  63. <el-card style="width: 30%;margin-right: 10px;">
  64. <div slot="header" class="clearfix">
  65. <span>青哥哥带你做毕设2024</span>
  66. </div>
  67. <div>
  68. 2024毕设正式开始了!青哥哥带你手把手敲出来!
  69. <div style="margin-top: 20px">
  70. <div style="margin: 10px 0"><strong>主题色</strong></div>
  71. <el-button type="primary">按钮</el-button>
  72. <el-button type="success">按钮</el-button>
  73. <el-button type="warning">按钮</el-button>
  74. <el-button type="danger">按钮</el-button>
  75. <el-button type="info">按钮</el-button>
  76. </div>
  77. </div>
  78. </el-card>
  79. <el-card style="width: 70%;">
  80. <div slot="header" class="clearfix">
  81. <span>渲染用户的数据</span>
  82. </div>
  83. <div>
  84. <el-table :data="users">
  85. <el-table-column label="ID" prop="id"/>
  86. <el-table-column label="用户名" prop="username"/>
  87. <el-table-column label="姓名" prop="name"/>
  88. <el-table-column label="地址" prop="address"/>
  89. <el-table-column label="文件上传">
  90. <template v-slot="scope">
  91. <el-upload
  92. action="http://localhost:9090/file/upload"
  93. :show-file-list="false"
  94. :headers="{token: user.token}"
  95. :on-success="(row,file,fileList)=>handleTableFileUpload(scope.row,file,fileList)"
  96. >
  97. <el-button size="mini" type="primary">点击上传</el-button>
  98. </el-upload>
  99. </template>
  100. </el-table-column>
  101. <el-table-column label="文件下载">
  102. <template v-slot="scope">
  103. <el-image v-if="scope.row.avatar" :src="scope.row.avatar" style="width: 50px;height: 50px"></el-image>
  104. <div>
  105. <el-button @click="preview(scope.row.avatar)">
  106. 预览
  107. </el-button>
  108. </div>
  109. </template>
  110. </el-table-column>
  111. </el-table>
  112. </div>
  113. </el-card>
  114. </div>
  115. <div style="display: flex;margin: 10px 0">
  116. <el-card style="width: 50%;margin-right: 10px;">
  117. <div slot="header" class="clearfix">
  118. <span>文件上传下载</span>
  119. </div>
  120. <div>
  121. <el-upload
  122. action="http://localhost:9090/file/upload"
  123. list-type="picture"
  124. :headers="{token: user.token}"
  125. :on-success="handleFileUpload"
  126. >
  127. <el-button size="small" type="primary">单文件上传</el-button>
  128. </el-upload>
  129. </div>
  130. <div style="margin: 10px 0">
  131. <el-upload
  132. action="http://localhost:9090/file/upload"
  133. :headers="{token: user.token}"
  134. :on-success="handleMutipleFileUpload"
  135. multiple
  136. >
  137. <el-button size="small" type="success">多文件上传</el-button>
  138. </el-upload>
  139. <el-button @click="showUrls" style="margin: 10px 0" type="primary">显示链接</el-button>
  140. </div>
  141. </el-card>
  142. </div>
  143. </el-main>
  144. </el-container>
  145. </el-container>
  146. </div>
  147. </template>
  148. <script>
  149. import axios from "axios";
  150. import request from '@/utils/request'
  151. export default {
  152. name: 'HomeView',
  153. data() {
  154. return {
  155. isCollapse: false, // 不收缩
  156. asideWidth: '200px',
  157. collapseIcon: 'el-icon-s-fold',
  158. users: [],
  159. user:JSON.parse(localStorage.getItem('honey-user')||'{}'),
  160. url:'',
  161. urls:[]
  162. }
  163. },
  164. mounted() {
  165. // axios.get('http://localhost:9090/user/selectall').then(res=>{
  166. // console.log(res.data);
  167. // this.users=res.data.data
  168. // })
  169. request.get('/user/selectall').then(res => {
  170. this.users = res.data
  171. })
  172. },
  173. methods: {
  174. preview(url){
  175. window.open(url)
  176. },
  177. showUrls(){
  178. console.log(this.urls)
  179. },
  180. handleMutipleFileUpload(response,file,fileList){
  181. this.urls=fileList.map(v=>v.response?.data)
  182. },
  183. handleTableFileUpload(row,file,fileList){
  184. console.log(row,file,fileList)
  185. row.avatar=file.response.data
  186. // this.$set(row,'avatar',file.response.data)
  187. console.log(row)
  188. request.put('/user/update',row).then(res=>{
  189. if(res.code==='200'){
  190. this.$message.success('上传成功')
  191. }else{
  192. this.$message.error(res.msg)
  193. }
  194. })
  195. },
  196. handleFileUpload(response,file,fileList){
  197. this.fileList=fileList
  198. console.log(response,file,fileList)
  199. },
  200. logout() {
  201. localStorage.removeItem("honey-user")
  202. this.$router.push('/login')
  203. },
  204. handleFull() {
  205. document.documentElement.requestFullscreen()
  206. },
  207. handleCollapse() {
  208. this.isCollapse = !this.isCollapse
  209. this.asideWidth = this.isCollapse ? '64px' : '200px'
  210. this.collapseIcon = this.isCollapse ? 'el-icon-s-unfold' : 'el-icon-s-fold'
  211. }
  212. }
  213. }
  214. </script>
  215. <style>
  216. .el-menu--inline {
  217. background-color: #000c17 !important;
  218. }
  219. .el-menu--inline .el-menu-item {
  220. background-color: #000c17 !important;
  221. padding-left: 49px !important;
  222. }
  223. .el-menu-item:hover, .el-submenu__title:hover {
  224. color: #fff !important;
  225. }
  226. .el-submenu__title:hover i {
  227. color: #fff !important;
  228. }
  229. .el-menu-item:hover i {
  230. color: #fff !important;
  231. }
  232. .el-menu-item.is-active {
  233. background-color: #1890ff !important;
  234. border-radius: 5px !important;
  235. width: calc(100% - 8px);
  236. margin-left: 4px;
  237. }
  238. .el-menu-item.is-active i, .el-menu-item.is-active .el-tooltip {
  239. margin-left: -4px;
  240. }
  241. .el-menu-item {
  242. height: 40px !important;
  243. line-height: 40px !important;
  244. }
  245. .el-submenu__title {
  246. height: 40px !important;
  247. line-height: 40px !important;
  248. }
  249. .el-submenu .el-menu-item {
  250. min-width: 0 !important;
  251. }
  252. .el-menu--inline .el-menu-item.is-active {
  253. padding-left: 45px !important;
  254. }
  255. /*.el-submenu__icon-arrow {*/
  256. /* margin-top: -5px;*/
  257. /*}*/
  258. .el-aside {
  259. transition: width .3s;
  260. box-shadow: 2px 0 6px rgba(0, 21, 41, .35);
  261. }
  262. .logo-title {
  263. margin-left: 5px;
  264. font-size: 20px;
  265. transition: all .3s; /* 0.3s */
  266. }
  267. .el-header {
  268. box-shadow: 2px 0 6px rgba(0, 21, 41, .35);
  269. display: flex;
  270. align-items: center;
  271. }
  272. </style>

 最后效果:实现了单文件或者多文件上传和预览下载的功能

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/377593
推荐阅读
相关标签
  

闽ICP备14008679号