【JavaWeb | 第十一篇】文件上传(本地&阿里云OSS)

目录

一、本地存储

[1.1 前端发送的参数](#1.1 前端发送的参数)

[1.2 后端处理](#1.2 后端处理)

二、阿里云OSS云端存储

[2.1 开通阿里云OSS服务](#2.1 开通阿里云OSS服务)

[2.2 创建Bucket](#2.2 创建Bucket)

[2.3 代码实现](#2.3 代码实现)

[2.4 程序优化-参数配置化](#2.4 程序优化-参数配置化)

[2.5 程序优化](#2.5 程序优化)


一、本地存储

1.1 前端发送的参数

前端页面:三个请求参数:name、age、file

注意:form标签当中的method要选post,enctype要填multipart/form-data才能确保文件成功上传。

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>上传文件</title>
</head>
<body>

    <form action="/upload" method="post" enctype="multipart/form-data">
        姓名: <input type="text" name="name"><br>
        年龄: <input type="text" name="age"><br>
        头像: <input type="file" name="file"><br>
        <input type="submit" value="提交">
    </form>

</body>
</html>

1.2 后端处理

Controller层

java 复制代码
    @PostMapping("/upload")
    public Result upload(String name, Integer age, MultipartFile file) throws IOException {
        log.info("接收到的参数为: {} {} {}",name, age, file);

        String originalFileName = file.getOriginalFilename();
        String extension = originalFileName.substring(originalFileName.lastIndexOf('.'));

        String newFileName = UUID.randomUUID().toString() + extension;
        file.transferTo(new File("D:/images/" + newFileName));
        return Result.success();
    }

要点1 :方法形参的个数和命名要与前端input标签中的name属性值保持一致。

要点2:在真实文件上传场景中,图片的命名可能会重复,因此我们使用UUID提供的随机UUID值来给文件命名。

要点3 :要保持源文件的文件类型,要把源文件的后缀属性(.png、.jpg)分割后拼接。

二、阿里云OSS云端存储

2.1 开通阿里云OSS服务

进入后会显示开通服务的按钮,点击即可开通对象存储OSS的服务。

2.2 创建Bucket

配置你的bucket信息

配置完成之后,参考下面的阿里云OSS用户手册将自己的AccessKey保存并设置为环境变量。

2.3 代码实现

在这里上传文件的代码基本上是固定的,因此可以将这个代码封装到一个工具类Utils中。

我直接将代码贴在这里,可以直接复制。

java 复制代码
package com.sprneft.utils;

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
import com.aliyun.oss.common.comm.SignVersion;
import org.springframework.stereotype.Component;
import java.io.ByteArrayInputStream;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.UUID;

@Component
public class AliyunOSSOperator {

    private String endpoint = "https://oss-cn-beijing.aliyuncs.com";
    private String bucketName = "java-web0924";
    private String region = "cn-beijing";

    public String upload(byte[] content, String originalFilename) throws Exception {
        // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();

        // 填写Object完整路径,例如202406/1.png。Object完整路径中不能包含Bucket名称。
        //获取当前系统日期的字符串,格式为 yyyy/MM
        String dir = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM"));
        //生成一个新的不重复的文件名
        String newFileName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf("."));
        String objectName = dir + "/" + newFileName;

        // 创建OSSClient实例。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();

        try {
            ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content));
        } finally {
            ossClient.shutdown();
        }

        return endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + objectName;
    }

}

修改上面本地存储的UploadController代码为云端存储,这个工具类需要传入两个参数,第一个参数为文件的字节数组 ,第二个参数为文件的初始命名

java 复制代码
    @PostMapping("/upload")
    public Result upload(MultipartFile file) throws Exception {
        log.info("上传的文件为:{}", file.getOriginalFilename());
        String url = aliyunOSSOperator.upload(file.getBytes(), file.getOriginalFilename());
        log.info("文件上传OSS,url为 {}", url);
        return Result.success(url);
    }

接下来点击上传文件就可以进行文件的上传了,并且这个文件是会保存到云端的。

2.4 程序优化-参数配置化

我们发现如果将endpoint、bucketName以及region在工具类中写死的话,不利于工程化的维护,我们需要一个类一个类的查找,因此我们可以将这些配置信息填写到application.yaml文件当中,并通过**@Value**注解来进行配置信息的注入。

加入的配置信息

XML 复制代码
aliyun:
  oss:
    endpoint: https://oss-cn-beijing.aliyuncs.com
    bucketName: java-web0924
    region: cn-beijing

注入**@Value**后的工具类首部:

java 复制代码
    @Value("${aliyun.oss.endpoint}")
    private String endpoint;
    @Value("${aliyun.oss.bucketName}")
    private String bucketName;
    @Value("${aliyun.oss.region}")
    private String region;

2.5 程序优化

使用@Value注解注入配置文件的配置项,如果配置项多,注入繁琐,不便于维护管理 和复用。

使用**@ConfigurationProperties**进行优化。

要点1 :要把配置中的属性封装到一个实体类当中,并赋予get、set方法(@Data),并且放到IOC容器当中(@Component)。

要点2:使用**@ConfigurationProperties**注解将配置yaml文件中的具体的值注入到实体类当中。

相关推荐
吾疾唯君医1 小时前
Java SpringBoot集成积木报表实操记录
java·spring boot·spring·导出excel·积木报表·数据文件下载
Byron Loong1 小时前
【c++】为什么有了dll和.h,还需要包含lib
java·开发语言·c++
hexu_blog2 小时前
vue+java实现图片批量压缩
java·前端·vue.js
头歌实践平台2 小时前
Hadoop开发环境搭建
java·大数据·hadoop
Seven972 小时前
一致性Hash算法:如何实现分布式系统中的高效数据分片?
java
摇滚侠2 小时前
IDEA 生成 try catch 快捷键
java·ide·intellij-idea
阿旭超级学得完3 小时前
C++11包装器(function和bind)
java·开发语言·c++·算法·哈希算法·散列表
掉鱼的猫4 小时前
Spring AI 2.0 GA 倒计时:先别急,来看看 Java AI 框架的另一条路
java·openai·agent