springboot中Controller内文件上传到本地及阿里云操作方法
作者:Ek-Georain
上传文件的基本操作
<form action="/upload" method="post" enctype="multipart/form-data"> <h1>登录</h1> 姓名:<input type="text" name="username" required><br> 年龄:<input type="text" name="age" required><br> 头像:<input type="file" name="file" required><br> <input type="submit" value="提交"> </form>
// Java接收前端发来的文件 @RestController public class UploadController { private static final ch.qos.logback.classic.Logger log = (Logger) LoggerFactory.getLogger(UploadController.class); @PostMapping(path = "/upload") public Result upload(String username, Integer age, MultipartFile file){ log.info("接收参数:" + username + age + file); return Result.success(); } }
注意:springboot项目启动后,打开这个index.html的页面要输入:localhost:8080/index.html
接下来通过断点调试获取查看前端发送过来的文件
文件的”到此一游“:该文件所在的路径的文件夹是个临时文件夹,运行完毕后这个文件夹里的内容清空
前端上传文件本地存储
@PostMapping("/upload") public Result upload(String name, Integer age, MultipartFile file) throws IOException { // 记录接收到的参数,包括姓名、年龄和文件 log.info("接收参数: {}, {}, {}", name, age, file); // 获取上传文件的原始文件名 String originalFilename = file.getOriginalFilename(); // 将文件保存到指定路径(D:/images/)并命名为原始文件名 file.transferTo(new File( "D:/idea/javacode/web/Getdata/" + originalFilename)); // 返回成功结果 return Result.success(); }
文件上传还存在一个要考虑的问题:如果两次提交的是不一样的文件,但是文件名称一样,那么第二次提交的图片会把第一次提交的文件给替换(覆盖)因此可以使用UUID命名来解决。
生成UUID
import java.util.UUID; public class UUIDExample { public static void main(String[] args) { // 生成一个随机UUID UUID uuid = UUID.randomUUID(); // 输出UUID System.out.println("生成的UUID: " + uuid.toString()); } }
使用UUID解决以上问题
@PostMapping("/upload") public Result upload(String name, Integer age, MultipartFile file) throws IOException { // 记录接收到的参数,包括姓名、年龄和文件 log.info("接收参数: {}, {}, {}", name, age, file); // 获取上传文件的原始文件名,例如 "1.jpg" 或 "22.2.2.2.png" String originalFilename = file.getOriginalFilename(); // 获取文件扩展名,从最后一个点后开始截取 String extension = originalFilename.substring(originalFilename.lastIndexOf(".")); // 生成新的文件名,使用UUID并加上文件扩展名 String newFileName = UUID.randomUUID().toString() + extension; // 将文件保存到指定路径(D:/images/)并命名为新的文件名 file.transferTo(new File("D:/images/" + newFileName)); // 返回成功结果 return Result.success(); }
file.transferTo(new File("D:/idea/javacode/web/Getdata/" + newFileName));
这个代码的路径最后一定要写个“/”,使得文件保存在那个文件夹下。
上传文件大小限制
默认上传文件的最大大小为1MB,超过该大小需要在配置文件配置
servlet: multipart: # 最大单个文件大小 max-file-size: 10MB # 最大请求大小(包括所有文件和表单数据) max-request-size: 100MB
阿里云OSS
阿里云对象存储oss(object Storage Service),是一款海量、安全、低成本、高可靠的云存储服务。使用oss
您可以通过网络随时存储和调用包括文本、图片、音频和视频等在内的各种文件。
具体怎么配看:视频
配置好相关密钥等配置后,创建bucket。接下来可以通过Java代码将自己电脑本地的文件上传到阿里云。
添加好下面的依赖
<dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>3.17.4</version> </dependency> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>javax.activation</groupId> <artifactId>activation</artifactId> <version>1.1.1</version> </dependency> <!-- no more than 2.3.3--> <dependency> <groupId>org.glassfish.jaxb</groupId> <artifactId>jaxb-runtime</artifactId> <version>2.3.3</version> </dependency>
具体的上传文件的代码
public static void main(String[] args) throws com.aliyuncs.exceptions.ClientException { /** * 基础配置:连接服务并验证个人身份 */ // Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。 String endpoint = "https://oss-cn-shenzhen.aliyuncs.com"; // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // 填写Bucket名称,例如examplebucket。 String bucketName = "q-buckets"; /** * 配置具体文件上传信息 */ // 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。 String objectName = "ph.webp"; // 可以修改名字 // 填写本地文件的完整路径,例如D:\\localpath\\examplefile.txt。 // 如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件。 String filePath= "D:\\Mycode\\webcode\\imag\\nu.webp"; // 创建OSSClient实例。 OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider); try { // 创建PutObjectRequest对象。 PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new File(filePath)); // 如果需要上传时设置存储类型和访问权限,请参考以下示例代码。 // ObjectMetadata metadata = new ObjectMetadata(); // metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString()); // metadata.setObjectAcl(CannedAccessControlList.Private); // putObjectRequest.setMetadata(metadata); // 上传文件。 PutObjectResult result = ossClient.putObject(putObjectRequest); } catch (OSSException oe) { System.out.println("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); System.out.println("Error Message:" + oe.getErrorMessage()); System.out.println("Error Code:" + oe.getErrorCode()); System.out.println("Request ID:" + oe.getRequestId()); System.out.println("Host ID:" + oe.getHostId()); } catch (ClientException ce) { System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message:" + ce.getMessage()); } finally { if (ossClient != null) { ossClient.shutdown(); } } }
这样就可以在自己阿里云的bucket里面看到上传的文件
参考:后端之路
文件上传操作整合为工具类并在Controller中使用
具体代码如下
@Component // 方便依赖注入 public class AliyunOSSOperation { // 指定阿里云OSS的服务地址,这里是深圳区域的地址 private String endpoint = "https://oss-cn-shenzhen.aliyuncs.com"; // 指定要上传到的存储桶名称 private String bucketName = "lwq-buckets"; // 指定阿里云的区域,这里是深圳区域 private String region = "cn-shenzhen"; /** * 上传文件到阿里云OSS * @param content 文件的字节数组内容 * @param originalFilename 原始文件名,用于生成新的文件名 * @return 上传后文件的访问路径 * @throws Exception 可能抛出的异常 */ public String upload(byte[] content, String originalFilename) throws Exception { // 从环境变量中获取访问密钥,确保在运行代码前设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // 获取object对象路径,例如2024/06/21.png。Object类型中不能包含Bucket名称 String dir = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM")); // 生成一个新的文件名,使用UUID确保唯一性,并保留原始文件的扩展名 String newFileName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf(".")); String objectName = dir + "/" + newFileName; // 生成完整的对象名称 // 创建OSSClient实例 ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); // 设置签名版本为V4 // 使用OSSClientBuilder创建OSS客户端实例,配置包括端点、凭证提供者、客户端配置和区域 OSS ossClient = OSSClientBuilder.create() .endpoint(endpoint) .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region(region) .build(); try { // 上传文件内容到指定的存储桶和对象路径 ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content)); } finally { // 确保无论上传是否成功,都会关闭OSS客户端 ossClient.shutdown(); } // 生成并返回文件的完整访问路径 return endpoint.split("//")[0] + "//" + bucketName + "." + endpoint.split("//")[1] + "/" + objectName; } }
使用该类
@Autowired // 自动注入AliyunOSSOperator实例 private AliyunOSSOperator aliyunOSSOperator; @PostMapping("/upload") // 定义一个POST请求处理方法,映射到/upload路径 public Result upload(MultipartFile file) throws Exception { // 记录上传文件的原始文件名到日志 log.info("文件上传: {}", file.getOriginalFilename()); // 调用aliyunOSSOperator的upload方法,将文件字节和文件名上传到OSS String url = aliyunOSSOperator.upload(file.getBytes(), file.getOriginalFilename()); // 记录文件上传后返回的URL到日志 log.info("文件上传OSS, url: {}", url); // 返回上传结果,包含文件的访问URL return Result.success(url); }
这样上传到阿里云的文件以年月划分了文件夹
参数配置进一步优化
指将一些需要灵活变化的参数,配置在配置文件中,然后通过 @Value 注解来注入外部配置的属性。
aliyun: oss: endpoint: https://oss-cn-beijing.aliyuncs.com bucketName: java-ai region: cn-beijing
以上配置信息配置在yml文件中
@Value("${aliyun.oss.endpoint}") private String endpoint; @Value("${aliyun.oss.bucketName}") private String bucketName; @Value("${aliyun.oss.region}") private String region;
到此这篇关于springboot中Controller内文件上传到本地及阿里云操作方法的文章就介绍到这了,更多相关springboot Controller文件上传内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!