文件上传模板
2022-08-03 09:57:03
111
{{single.collect_count}}

文件上传-本地上传

概述

使用场景

文件上传是程序开发中都会用到的一个需求,一般用来共享资源。比如:

  • 添加用户头像,文章封面…
  • 富文本编辑(插件文件上传)

原理

用户选择文件发送request请求,程序将文件通过Java-IO流复制到服务器即为文件上传

用SpringBoot实现文件上传

1. 实现步骤

01. 搭建SpringBoot工程

  • 新建项目
    在这里插入图片描述
  • 配置端口
server:port: 8888spring:freemarker:suffix: .htmlcache: false

02. 准备文件上传的前端页面

  • 创建resources/templates/upload.html
 <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>文件上传</title></head><body><h1 style="text-align: center">文件上传</h1><form action="/upload/file" enctype="multipart/form-data" method="post"><input name="dir" value="bbs"><input name="file" type="file"><input type="submit" value="文件上传"></form></body></html>

03. 实现文件上传的后端逻辑

  • 定义文件上传service:UploadService

此处需要注意:

  • mkdirs()可建立多级文件夹
  • mkdir()只建立一级文件夹
package com.yue.service;import org.springframework.stereotype.Service;import org.springframework.web.multipart.MultipartFile;import java.io.File;import java.io.IOException;/** * @Author: 夜雨 * Create Date Time: 2022-02-26-21:54 * Update Date Time: * @Version 1.0 * @Description: * @see */@Servicepublic class UploadService {/** * @Discription: MultipartFile对象是一个SpringMVC提供的文件上传接收类 * 其底层会自动去与HttpServletRequest request中的request.getInputStream()融合,从而实现文件上传 * 所以:文件上传底层原理就是request.getInputStream() * @param multipartFile * @param dir * @return java.lang.String * @Author: 夜雨 * @Date: 2022/3/1 20:55 */public String uploadImg(MultipartFile multipartFile,String dir){File targetFile = new File("G://tmp/"+dir);try {if (!targetFile.exists())targetFile.mkdir();multipartFile.transferTo(targetFile);return "上传成功";} catch (IOException e) {e.printStackTrace();return "上传失败!";}}}
  • 定义文件上传controller:UploadController
package com.yue.controller;import com.yue.service.UploadService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletRequest;/** * @Author: 夜雨 * Create Date Time: 2022-02-26-21:53 * Update Date Time: * @Version 1.0 * @Description: * @see */@Controllerpublic class UploadController {@Autowiredprivate UploadService uploadService;/** * @Discription: 文件上传 * @param multipartFile * @param request * @return java.lang.String * @Author: 夜雨 * @Date: 2022/2/28 21:27 */@PostMapping("/upload/file")@ResponseBodypublic String upload(@RequestParam("file") MultipartFile multipartFile, HttpServletRequest request){if (multipartFile.isEmpty()){return "文件有误!";}String dir = request.getParameter("dir");return uploadService.uploadImg(multipartFile,dir);}}
  • 测试上传,在后台看到如下:
    在这里插入图片描述
    SpringMVC提供了MultipartFile包装对象,原理如下:
    在这里插入图片描述

通过MultipartFile 我们很清楚的看到,文件已经被服务器接收。
但是会产生一个临时目录,这个目录是可以去配置

文件上传不会直接上传真正的目录,它一定要经过一个临时目录的中转以后,才会上传到真正的目录。作用:

  • 防止上传出现网络断开,或者用户上传直接刷新或者取消。因为如果用户的网络断开或者取消,就造成大量的垃圾文件
  • 保证真实目录上传的文件一定是有效的。
  • 文件上传的大小:也可以进行配置的
  • 文件上传的类型:也是进行配置的
server:port: 8888spring:freemarker:suffix: .htmlcache: falseservlet:multipart:enabled: true#当文件大小达到多少时进行磁盘写入file-size-threshold: 1KB#单个文件的最大值(默认1MB)max-file-size: 50MB#一次性上传文件的最大值max-request-size: 800MB#指定临时目录location: D://data//temptest

注意配置临时目录的时候需要些两个“/”,因为需要转义
在这里插入图片描述
在这里插入图片描述

04. 配置静态资源存储服务(指定文件存储目录)

增加日期目录,确定文件存放最终目录

package com.yue.service;import org.springframework.stereotype.Service;import org.springframework.web.multipart.MultipartFile;import java.io.File;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.*;/** * @Author: 夜雨 * Create Date Time: 2022-02-26-21:54 * Update Date Time: * @Version 1.0 * @Description: * @see */@Servicepublic class UploadService<contentType> {private ArrayList<String> contentTypeList;/** * @Discription: MultipartFile对象是一个SpringMVC提供的文件上传接收类 * 其底层会自动去与HttpServletRequest request中的request.getInputStream()融合,从而实现文件上传 * 所以:文件上传底层原理就是request.getInputStream() * @param multipartFile * @param dir * @return java.lang.String * @Author: 夜雨 * @Date: 2022/3/1 20:55 */public String uploadImg(MultipartFile multipartFile,String dir) {//1.指定文件上传目录try {//1.获取文件名String realFilename = multipartFile.getOriginalFilename();//2.截取文件后缀名String imgSuffix = realFilename.substring(realFilename.lastIndexOf("."));//3.生成唯一文件名(不能使用中文命名,在网页访问过程中统一英文命名,中文名可能会出现乱码,需要进一步处理)String newFilename = UUID.randomUUID().toString() + imgSuffix;//4.生成日期目录SimpleDateFormat dateFormat = new SimpleDateFormat("yyy/MM/dd");String dataPath = dateFormat.format(new Date());//5.指定最终目录File targetPath = new File("D://tmp/" + dir, dataPath);if (!targetPath.exists()) targetPath.mkdirs();//不存在目录则创建//6.指定文件上传后服务器的完整文件名File targetFileName = new File(targetPath, newFilename);//7.文件上传multipartFile.transferTo(targetFileName);return "上传成功";} catch (IOException e) {e.printStackTrace();return "上传失败!";}}}

在这里插入图片描述

限制上传文件的类型(类型隔离)
  • 前端实现:

“accept”属性:接收类型

<form action="/upload/file" enctype="multipart/form-data" method="post"><input name="dir" value="bbs"><input name="file" type="file" accept="image/png"><input type="submit" value="文件上传"></form>

作用:上传文件时自动过滤类型,但是仍可以在前端手动选择所有文件,所以文件类型限制一般在后端实现。
在这里插入图片描述

  • 后端实现

05. 通过Http://去访问程序

06. 程序优化

回帖
全部回帖({{commentCount}})
{{item.user.nickname}} {{item.user.group_title}} {{item.friend_time}}
{{item.content}}
{{item.comment_content_show ? '取消' : '回复'}} 删除
回帖
{{reply.user.nickname}} {{reply.user.group_title}} {{reply.friend_time}}
{{reply.content}}
{{reply.comment_content_show ? '取消' : '回复'}} 删除
回帖
收起
没有更多啦~
{{commentLoading ? '加载中...' : '查看更多评论'}}