苍穹外卖(五)文件上传

1、简介
  • 文件上传,是指将本地图片、视频、音频、等文件上传到服务器,供其他用户浏览下载的过程
  • 文件上传在项目中应用非常广泛,我们经常发微博、发微信朋友圈都用到了文件上传功能

image-20240512205748833

2、如何进行图片传输

前端页面三要素:

  1. 表单项 type = “file”: 在 HTML 表单中,确保你的文件上传字段使用了 input 标签,且 type 属性设置为 "file"。这样用户就可以通过点击按钮或者拖拽文件的方式选择要上传的图片文件。

    htmlCopy code<form action="/upload" method="post" enctype="multipart/form-data">
        <input type="file" name="imageFile">
        <!-- 其他表单项 -->
        <button type="submit">上传</button>
    </form>
    
  2. 表单提交方式 post: 确保你的表单提交方式为 POST 方法,因为文件上传通常需要发送大量数据,POST 方法更适合这种情况。

  3. 表单的 enctype 属性 multipart/form-data: 当表单中包含文件上传时,确保你设置了 enctype 属性为 "multipart/form-data",这样表单数据将以多部分形式进行编码,包括文件数据。

服务端接收文件:

  1. 使用 request.getInputStream() 解析文件数据: 在 Spring MVC 中,可以通过 HttpServletRequest 对象的 getInputStream() 方法获取请求的输入流,从而获取上传的文件数据。
  2. 封装数据给 MultipartFile Spring 框架提供了 MultipartFile 接口用于表示上传的文件。你可以将从 request.getInputStream() 获取的文件数据封装成 MultipartFile 对象,以便在 Spring MVC 中更方便地处理文件上传。
  3. 通过 MultipartFile 对象操作文件: 一旦文件被封装成 MultipartFile 对象,你就可以通过这个对象获取文件的内容、文件名、大小、内容类型等信息。此外,你还可以使用 MultipartFile 对象提供的方法将文件保存到服务器的任意位置。

整体流程就是,前端页面通过表单上传图片文件,服务端接收到请求后解析文件数据并保存或处理文件。

3、本地存储文件上传

当客户端发送 POST 请求到 /admin/common/upload 接口时,服务端会接收到上传的文件,并将其存储在本地服务器磁盘的指定目录中。

具体流程如下:

  1. 首先,服务端通过 @PostMapping("/upload") 注解将 /admin/common/upload 接口映射到了 upload() 方法。
  2. upload() 方法中,通过方法参数 MultipartFile file 接收客户端上传的文件数据。
  3. 生成一个唯一的文件名,确保文件名的唯一性。这里使用了原始文件名的后缀作为新文件名的后缀,并且在文件名前面添加了 UUID 以确保唯一性。
  4. 使用 transferTo() 方法将文件保存到本地服务器磁盘的指定目录中。这里直接使用了硬编码的路径 "d:\\file\\img\\",你也可以根据自己的需求进行配置。
  5. 最后,返回一个成功的结果给客户端,通知文件上传成功。
@RestController
@RequestMapping("/admin/common")
@Slf4j
public class CommonController {
   

    @PostMapping("/upload")
    public Result upload(MultipartFile file) throws IOException {
   
        //获取上传文件存储到D:\file\img目录下,并文件名使用uuid生成

        //1、生成唯一文件名
        //获取原始文件名
        String originalFilename = file.getOriginalFilename();
        String extName = originalFilename.substring(originalFilename.lastIndexOf("."));

        //定义唯一文件名
        String fileName = UUID.randomUUID() + extName;

        //2、保存到磁盘上
        file.transferTo(new File("d:\\file\\img\\"+fileName));

        //3、返回成功
        return Result.success();
    }
}

**注意:**在SpringBoot,文件上传,默认单个文件允许最大大小为1m,如果需要上传大文件,可以进行如下配置

servlet:
  multipart:
    max-file-size: 10MB  #一次请求上传单个文件限制
    max-request-size: 100MB #一次请求上传多个文件限制
4、云服务
### 苍穹外卖 图片上传 不使用OSS 解决方案 为了处理苍穹外卖应用中图片上传不依赖于阿里云对象存储服务(OSS),可以考虑采用本地服务器来保存这些图像资源。这意味着所有的菜品图片都将被直接存放在运行应用程序的同一台物理机器上的指定目录内。 当用户通过前端界面提交一张新的菜品照片时,后台程序会接收该请求并将接收到的数据流写入到预先配置好的文件夹位置[^3]。具体来说: - **创建专门用于存放图片的文件夹**:在Web服务器根路径下建立名为`uploads`或其他适当名称的新文件夹作为目标储存空间。 - **调整表单数据传输方式**:确保HTML页面内的<form>标签包含了属性enctype="multipart/form-data"以便能够发送二进制类型的多媒体资料给后端处理器。 - **编写控制器逻辑**:对于基于Spring Boot框架构建的应用而言,则需定义@RequestMapping("/upload")这样的映射规则,并在其内部实现MultipartFile接口方法获取客户端传递过来的实际文件实体;接着调用transferTo()函数完成最终落地过程。 下面是一个简单的Java代码片段展示如何实现上述描述的功能: ```java import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @RestController public class ImageUploadController { private static String UPLOADED_FOLDER = "path/to/the/directory/"; @PostMapping("/upload") public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) { if (file.isEmpty()) { return ResponseEntity.badRequest().body("Please select a file to upload"); } try { byte[] bytes = file.getBytes(); Path path = Paths.get(UPLOADED_FOLDER + file.getOriginalFilename()); Files.write(path, bytes); return ResponseEntity.ok("You successfully uploaded '" + file.getOriginalFilename() + "'"); } catch (IOException e) { e.printStackTrace(); } return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); } } ``` 值得注意的是,虽然这种方法简单易行,但在实际生产环境中部署之前还需要考虑到安全性、性能优化以及容错机制等方面因素。例如设置合理的最大允许尺寸限制防止恶意攻击者上传超大文件占用过多磁盘空间;定期备份重要文档以防意外丢失等措施都是必不可少的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小林学习编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值