mirror of
https://gitee.com/lxp135/minio-plus.git
synced 2025-12-06 17:08:26 +08:00
initial spring-boot 3 supports
This commit is contained in:
parent
6e84322c79
commit
91f2a84105
7
.gitignore
vendored
7
.gitignore
vendored
@ -16,3 +16,10 @@ buildNumber.properties
|
|||||||
# JDT-specific (Eclipse Java Development Tools)
|
# JDT-specific (Eclipse Java Development Tools)
|
||||||
.classpath
|
.classpath
|
||||||
/docs/.vitepress/cache/
|
/docs/.vitepress/cache/
|
||||||
|
|
||||||
|
# IDEA
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# logs
|
||||||
|
**/logs
|
||||||
|
**/*.log
|
||||||
@ -34,6 +34,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-validation</artifactId>
|
<artifactId>spring-boot-starter-validation</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.mysql</groupId>
|
<groupId>com.mysql</groupId>
|
||||||
|
|||||||
@ -4,18 +4,20 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SpringMVC配置
|
* SpringMVC配置
|
||||||
|
*
|
||||||
* @author contact@liuxp.me
|
* @author contact@liuxp.me
|
||||||
* @since 2024/06/11
|
* @since 2024/06/11
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
public class WebMvcConfig implements WebMvcConfigurer {
|
public class WebMvcConfig implements WebMvcConfigurer {
|
||||||
|
|
||||||
@Resource
|
private final LoginUserInterceptor loginUserInterceptor;
|
||||||
private LoginUserInterceptor loginUserInterceptor;
|
|
||||||
|
public WebMvcConfig(LoginUserInterceptor loginUserInterceptor) {
|
||||||
|
this.loginUserInterceptor = loginUserInterceptor;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 前置拦截器
|
* 前置拦截器
|
||||||
|
|||||||
@ -29,6 +29,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-validation</artifactId>
|
<artifactId>spring-boot-starter-validation</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.mysql</groupId>
|
<groupId>com.mysql</groupId>
|
||||||
|
|||||||
@ -7,11 +7,11 @@ import org.liuxp.minioplus.api.model.vo.FileMetadataInfoVo;
|
|||||||
import org.springframework.scheduling.annotation.Scheduled;
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 定时任务,演示工程定期清理文件
|
* 定时任务,演示工程定期清理文件
|
||||||
|
*
|
||||||
* @author contact@liuxp.me
|
* @author contact@liuxp.me
|
||||||
* @since 2024/06/17
|
* @since 2024/06/17
|
||||||
*/
|
*/
|
||||||
@ -19,8 +19,11 @@ import java.util.List;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class CleanTask {
|
public class CleanTask {
|
||||||
|
|
||||||
@Resource
|
private final StorageService storageService;
|
||||||
private StorageService storageService;
|
|
||||||
|
public CleanTask(StorageService storageService) {
|
||||||
|
this.storageService = storageService;
|
||||||
|
}
|
||||||
|
|
||||||
@Scheduled(cron = "0 0 */1 * * ?")
|
@Scheduled(cron = "0 0 */1 * * ?")
|
||||||
public void clean() {
|
public void clean() {
|
||||||
|
|||||||
@ -16,23 +16,12 @@
|
|||||||
<maven.compiler.source>17</maven.compiler.source>
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
<maven.compiler.target>17</maven.compiler.target>
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<springboot3.version>3.3.2</springboot3.version>
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>me.liuxp</groupId>
|
<groupId>me.liuxp</groupId>
|
||||||
<artifactId>minio-plus-all-springboot3-starter</artifactId>
|
<artifactId>minio-plus-all-springboot3-starter</artifactId>
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>me.liuxp</groupId>
|
<groupId>me.liuxp</groupId>
|
||||||
@ -46,35 +35,45 @@
|
|||||||
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
|
<!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.baomidou</groupId>
|
<groupId>com.baomidou</groupId>
|
||||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
|
||||||
</dependency>
|
<version>${mybatisplus.version}</version>
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter</artifactId>
|
|
||||||
<version>${springboot3.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
|
||||||
<version>${springboot3.version}</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-validation</artifactId>
|
<artifactId>spring-boot-starter-validation</artifactId>
|
||||||
<version>${springboot3.version}</version>
|
<version>${spring-boot3.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-jdbc</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.mysql</groupId>
|
<groupId>com.mysql</groupId>
|
||||||
<artifactId>mysql-connector-j</artifactId>
|
<artifactId>mysql-connector-j</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<!-- spring-boot-dependencies -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-dependencies</artifactId>
|
||||||
|
<version>${spring-boot3.version}</version>
|
||||||
|
<type>pom</type>
|
||||||
|
<scope>import</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
<version>${springboot3.version}</version>
|
<version>${spring-boot3.version}</version>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
<goals>
|
<goals>
|
||||||
|
|||||||
@ -8,8 +8,8 @@ import org.springframework.stereotype.Component;
|
|||||||
import org.springframework.web.servlet.HandlerInterceptor;
|
import org.springframework.web.servlet.HandlerInterceptor;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录用户拦截器
|
* 登录用户拦截器
|
||||||
|
|||||||
@ -4,18 +4,21 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SpringMVC配置
|
* SpringMVC配置
|
||||||
|
*
|
||||||
* @author contact@liuxp.me
|
* @author contact@liuxp.me
|
||||||
* @since 2024/06/11
|
* @since 2024/06/11
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
public class WebMvcConfig implements WebMvcConfigurer {
|
public class WebMvcConfig implements WebMvcConfigurer {
|
||||||
|
|
||||||
@Resource
|
private final LoginUserInterceptor loginUserInterceptor;
|
||||||
private LoginUserInterceptor loginUserInterceptor;
|
|
||||||
|
public WebMvcConfig(LoginUserInterceptor loginUserInterceptor) {
|
||||||
|
this.loginUserInterceptor = loginUserInterceptor;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 前置拦截器
|
* 前置拦截器
|
||||||
|
|||||||
@ -24,11 +24,15 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter</artifactId>
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- 自定义的配置类生成元数据信息 -->
|
<!-- 自定义的配置类生成元数据信息 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
@ -1,16 +1,10 @@
|
|||||||
package org.liuxp.minioplus.common.config;
|
package org.liuxp.minioplus.common.config;
|
||||||
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MinioPlusProperties自动配置类
|
* MinioPlus自动配置类
|
||||||
|
*
|
||||||
* @author contact@liuxp.me
|
* @author contact@liuxp.me
|
||||||
*/
|
*/
|
||||||
public class MinioPlusConfig {
|
public class MinioPlusConfig {
|
||||||
|
// do noting cuz use components scan
|
||||||
@Bean
|
|
||||||
public MinioPlusProperties tosProperties() {
|
|
||||||
return new MinioPlusProperties();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -5,6 +5,7 @@ import lombok.Getter;
|
|||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MinioPlus配置类
|
* MinioPlus配置类
|
||||||
@ -14,6 +15,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
|||||||
*/
|
*/
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
|
@Configuration
|
||||||
@ConfigurationProperties(prefix = "minioplus")
|
@ConfigurationProperties(prefix = "minioplus")
|
||||||
public class MinioPlusProperties {
|
public class MinioPlusProperties {
|
||||||
|
|
||||||
|
|||||||
@ -1,2 +0,0 @@
|
|||||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
|
||||||
org.liuxp.minioplus.common.config.MinioPlusConfig
|
|
||||||
@ -0,0 +1 @@
|
|||||||
|
org.liuxp.minioplus.common.config.MinioPlusConfig
|
||||||
@ -19,6 +19,12 @@
|
|||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>me.liuxp</groupId>
|
<groupId>me.liuxp</groupId>
|
||||||
<artifactId>minio-plus-common</artifactId>
|
<artifactId>minio-plus-common</artifactId>
|
||||||
|
|||||||
@ -26,7 +26,6 @@ import org.liuxp.minioplus.s3.def.ListParts;
|
|||||||
import org.liuxp.minioplus.s3.def.MinioS3Client;
|
import org.liuxp.minioplus.s3.def.MinioS3Client;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
@ -44,14 +43,17 @@ import java.util.Optional;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class StorageEngineServiceImpl implements StorageEngineService {
|
public class StorageEngineServiceImpl implements StorageEngineService {
|
||||||
|
|
||||||
@Resource
|
private final MetadataRepository metadataRepository;
|
||||||
MetadataRepository metadataRepository;
|
|
||||||
|
|
||||||
@Resource
|
private final MinioPlusProperties properties;
|
||||||
MinioPlusProperties properties;
|
|
||||||
|
|
||||||
@Resource
|
private final MinioS3Client minioS3Client;
|
||||||
MinioS3Client minioS3Client;
|
|
||||||
|
public StorageEngineServiceImpl(MetadataRepository metadataRepository, MinioPlusProperties properties, MinioS3Client minioS3Client) {
|
||||||
|
this.metadataRepository = metadataRepository;
|
||||||
|
this.properties = properties;
|
||||||
|
this.minioS3Client = minioS3Client;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传任务初始化
|
* 上传任务初始化
|
||||||
@ -538,6 +540,7 @@ public class StorageEngineServiceImpl implements StorageEngineService {
|
|||||||
* @param fileSize 文件大小
|
* @param fileSize 文件大小
|
||||||
* @return {@link Integer}
|
* @return {@link Integer}
|
||||||
*/
|
*/
|
||||||
|
@Override
|
||||||
public Integer computeChunkNum(Long fileSize) {
|
public Integer computeChunkNum(Long fileSize) {
|
||||||
// 计算分块数量
|
// 计算分块数量
|
||||||
double tempNum = (double) fileSize / properties.getPart().getSize();
|
double tempNum = (double) fileSize / properties.getPart().getSize();
|
||||||
|
|||||||
@ -26,13 +26,13 @@ import org.liuxp.minioplus.core.engine.StorageEngineService;
|
|||||||
import org.liuxp.minioplus.core.repository.MetadataRepository;
|
import org.liuxp.minioplus.core.repository.MetadataRepository;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 存储组件Service层公共方法实现类
|
* 存储组件Service层公共方法实现类
|
||||||
|
*
|
||||||
* @author contact@liuxp.me
|
* @author contact@liuxp.me
|
||||||
* @since 2023/06/26
|
* @since 2023/06/26
|
||||||
*/
|
*/
|
||||||
@ -42,20 +42,23 @@ public class StorageServiceImpl implements StorageService {
|
|||||||
/**
|
/**
|
||||||
* 存储引擎Service接口定义
|
* 存储引擎Service接口定义
|
||||||
*/
|
*/
|
||||||
@Resource
|
private final StorageEngineService storageEngineService;
|
||||||
StorageEngineService storageEngineService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件元数据服务接口定义
|
* 文件元数据服务接口定义
|
||||||
*/
|
*/
|
||||||
@Resource
|
private final MetadataRepository fileMetadataRepository;
|
||||||
MetadataRepository fileMetadataRepository;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MinioPlus配置信息注入类
|
* MinioPlus配置信息注入类
|
||||||
*/
|
*/
|
||||||
@Resource
|
private final MinioPlusProperties properties;
|
||||||
MinioPlusProperties properties;
|
|
||||||
|
public StorageServiceImpl(StorageEngineService storageEngineService, MetadataRepository fileMetadataRepository, MinioPlusProperties properties) {
|
||||||
|
this.storageEngineService = storageEngineService;
|
||||||
|
this.fileMetadataRepository = fileMetadataRepository;
|
||||||
|
this.properties = properties;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public FilePreShardingVo sharding(long fileSize) {
|
public FilePreShardingVo sharding(long fileSize) {
|
||||||
@ -290,6 +293,7 @@ public class StorageServiceImpl implements StorageService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 重写文件地址
|
* 重写文件地址
|
||||||
|
*
|
||||||
* @param url 文件地址
|
* @param url 文件地址
|
||||||
* @return 重写后的文件地址
|
* @return 重写后的文件地址
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,3 +0,0 @@
|
|||||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
|
||||||
org.liuxp.minioplus.core.service.impl.StorageServiceImpl,\
|
|
||||||
org.liuxp.minioplus.core.engine.impl.StorageEngineServiceImpl
|
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
#org.liuxp.minioplus.core.service.impl.StorageServiceImpl
|
||||||
|
#org.liuxp.minioplus.core.engine.impl.StorageEngineServiceImpl
|
||||||
@ -20,7 +20,15 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!--<dependency>
|
||||||
|
<groupId>jakarta.servlet</groupId>
|
||||||
|
<artifactId>jakarta.servlet-api</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>-->
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
@ -0,0 +1,111 @@
|
|||||||
|
package org.liuxp.minioplus.extension.controller;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.liuxp.minioplus.api.model.vo.FileCheckResultVo;
|
||||||
|
import org.liuxp.minioplus.api.model.vo.FilePreShardingVo;
|
||||||
|
import org.liuxp.minioplus.extension.context.Response;
|
||||||
|
import org.liuxp.minioplus.extension.dto.FileCheckDTO;
|
||||||
|
import org.liuxp.minioplus.extension.dto.FileCompleteDTO;
|
||||||
|
import org.liuxp.minioplus.extension.dto.PreShardingDTO;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对象存储标准接口定义
|
||||||
|
* 本类的方法是给前端使用的方法
|
||||||
|
*
|
||||||
|
* @author contact@liuxp.me
|
||||||
|
* @since 2024/6/18
|
||||||
|
*/
|
||||||
|
@Tag(name = "MinIO Plus 接口")
|
||||||
|
public interface StorageWebAPI {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求地址前缀
|
||||||
|
*/
|
||||||
|
String ROOT_PATH = "/storage";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图标请求地址
|
||||||
|
*/
|
||||||
|
String ICON_PATH = "/storage/icon/";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件预分片方法
|
||||||
|
* 在大文件上传时,为了防止前端重复计算文件MD5值,提供该方法
|
||||||
|
*
|
||||||
|
* @param preShardingDTO 文件预分片入参DTO
|
||||||
|
* @return 预分片结果
|
||||||
|
*/
|
||||||
|
@Operation(summary = "文件预分片")
|
||||||
|
@PostMapping("/upload/sharding")
|
||||||
|
@ResponseBody
|
||||||
|
Response<FilePreShardingVo> sharding(@RequestBody @Validated PreShardingDTO preShardingDTO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传任务初始化
|
||||||
|
* 上传前的预检查:秒传、分块上传和断点续传等特性均基于该方法实现
|
||||||
|
*
|
||||||
|
* @param fileCheckDTO 文件预检查入参
|
||||||
|
* @return 检查结果
|
||||||
|
*/
|
||||||
|
@Operation(summary = "上传任务初始化")
|
||||||
|
@PostMapping("/upload/init")
|
||||||
|
@ResponseBody
|
||||||
|
Response<FileCheckResultVo> init(@RequestBody @Validated FileCheckDTO fileCheckDTO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件上传完成
|
||||||
|
*
|
||||||
|
* @param fileKey 文件KEY
|
||||||
|
* @param fileCompleteDTO 文件完成入参DTO
|
||||||
|
* @return 是否成功
|
||||||
|
*/
|
||||||
|
@Operation(summary = "上传完成")
|
||||||
|
@PostMapping("/upload/complete/{fileKey}")
|
||||||
|
@ResponseBody
|
||||||
|
Response<Object> complete(@PathVariable("fileKey") String fileKey, @RequestBody FileCompleteDTO fileCompleteDTO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件下载
|
||||||
|
*
|
||||||
|
* @param fileKey 文件KEY
|
||||||
|
* @return 文件下载地址
|
||||||
|
*/
|
||||||
|
@Operation(summary = "文件下载")
|
||||||
|
@GetMapping("/download/{fileKey}")
|
||||||
|
String download(@PathVariable("fileKey") String fileKey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取图像
|
||||||
|
*
|
||||||
|
* @param fileKey 文件KEY
|
||||||
|
* @return 原图地址
|
||||||
|
*/
|
||||||
|
@Operation(summary = "图片预览 - 原图")
|
||||||
|
@GetMapping("/image/{fileKey}")
|
||||||
|
String previewOriginal(@PathVariable("fileKey") String fileKey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件预览
|
||||||
|
* 当文件为图片时,返回图片的缩略图
|
||||||
|
* 当文件不是图片时,返回文件类型图标
|
||||||
|
*
|
||||||
|
* @param fileKey 文件KEY
|
||||||
|
* @return 缩略图地址
|
||||||
|
*/
|
||||||
|
@Operation(summary = "图片预览 - 缩略图")
|
||||||
|
@GetMapping("/preview/{fileKey}")
|
||||||
|
String previewMedium(@PathVariable("fileKey") String fileKey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据文件类型取得图标
|
||||||
|
*
|
||||||
|
* @param fileType 文件扩展名
|
||||||
|
*/
|
||||||
|
@Operation(summary = "获取图标")
|
||||||
|
@GetMapping("/icon/{fileType}")
|
||||||
|
void icon(@PathVariable("fileType") String fileType);
|
||||||
|
|
||||||
|
}
|
||||||
@ -26,6 +26,13 @@
|
|||||||
<groupId>me.liuxp</groupId>
|
<groupId>me.liuxp</groupId>
|
||||||
<artifactId>minio-plus-common</artifactId>
|
<artifactId>minio-plus-common</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-log4j12</artifactId>
|
||||||
|
<version>1.7.36</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
@ -9,14 +9,12 @@ import io.minio.errors.XmlParserException;
|
|||||||
import io.minio.http.Method;
|
import io.minio.http.Method;
|
||||||
import io.minio.messages.Part;
|
import io.minio.messages.Part;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.liuxp.minioplus.common.config.MinioPlusProperties;
|
||||||
import org.liuxp.minioplus.common.enums.MinioPlusErrorCode;
|
import org.liuxp.minioplus.common.enums.MinioPlusErrorCode;
|
||||||
import org.liuxp.minioplus.common.exception.MinioPlusException;
|
import org.liuxp.minioplus.common.exception.MinioPlusException;
|
||||||
import org.liuxp.minioplus.common.config.MinioPlusProperties;
|
|
||||||
import org.liuxp.minioplus.s3.def.ListParts;
|
import org.liuxp.minioplus.s3.def.ListParts;
|
||||||
import org.liuxp.minioplus.s3.def.MinioS3Client;
|
import org.liuxp.minioplus.s3.def.MinioS3Client;
|
||||||
import org.springframework.stereotype.Repository;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
@ -29,7 +27,6 @@ import java.util.concurrent.ExecutionException;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Repository
|
|
||||||
public class MinioS3ClientImpl implements MinioS3Client {
|
public class MinioS3ClientImpl implements MinioS3Client {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,11 +38,14 @@ public class MinioS3ClientImpl implements MinioS3Client {
|
|||||||
*/
|
*/
|
||||||
private static final String PART_NUMBER = "partNumber";
|
private static final String PART_NUMBER = "partNumber";
|
||||||
|
|
||||||
@Resource
|
private final MinioPlusProperties properties;
|
||||||
private MinioPlusProperties properties;
|
|
||||||
|
|
||||||
private CustomMinioClient minioClient = null;
|
private CustomMinioClient minioClient = null;
|
||||||
|
|
||||||
|
public MinioS3ClientImpl(MinioPlusProperties properties) {
|
||||||
|
this.properties = properties;
|
||||||
|
}
|
||||||
|
|
||||||
public CustomMinioClient getClient() {
|
public CustomMinioClient getClient() {
|
||||||
|
|
||||||
if (null == this.minioClient) {
|
if (null == this.minioClient) {
|
||||||
@ -63,8 +63,9 @@ public class MinioS3ClientImpl implements MinioS3Client {
|
|||||||
public Boolean bucketExists(String bucketName) {
|
public Boolean bucketExists(String bucketName) {
|
||||||
try {
|
try {
|
||||||
return this.getClient().bucketExists(BucketExistsArgs.builder().bucket(bucketName).build()).get();
|
return this.getClient().bucketExists(BucketExistsArgs.builder().bucket(bucketName).build()).get();
|
||||||
} catch (InsufficientDataException | InternalException | InvalidKeyException | IOException | NoSuchAlgorithmException | XmlParserException | ExecutionException | InterruptedException e) {
|
} catch (InsufficientDataException | InternalException | InvalidKeyException | IOException |
|
||||||
log.error(MinioPlusErrorCode.BUCKET_EXISTS_FAILED.getMessage()+":{}", e.getMessage(), e);
|
NoSuchAlgorithmException | XmlParserException | ExecutionException | InterruptedException e) {
|
||||||
|
log.error("{}:{}", MinioPlusErrorCode.BUCKET_EXISTS_FAILED.getMessage(), e.getMessage(), e);
|
||||||
throw new MinioPlusException(MinioPlusErrorCode.BUCKET_EXISTS_FAILED);
|
throw new MinioPlusException(MinioPlusErrorCode.BUCKET_EXISTS_FAILED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,7 +79,7 @@ public class MinioS3ClientImpl implements MinioS3Client {
|
|||||||
this.getClient().makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
|
this.getClient().makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(MinioPlusErrorCode.MAKE_BUCKET_FAILED.getMessage()+":{}", e.getMessage(), e);
|
log.error("{}:{}", MinioPlusErrorCode.MAKE_BUCKET_FAILED.getMessage(), e.getMessage(), e);
|
||||||
throw new MinioPlusException(MinioPlusErrorCode.MAKE_BUCKET_FAILED);
|
throw new MinioPlusException(MinioPlusErrorCode.MAKE_BUCKET_FAILED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,7 +90,7 @@ public class MinioS3ClientImpl implements MinioS3Client {
|
|||||||
CreateMultipartUploadResponse createMultipartUploadResponse = this.getClient().createMultipartUpload(bucketName, null, objectName, null, null);
|
CreateMultipartUploadResponse createMultipartUploadResponse = this.getClient().createMultipartUpload(bucketName, null, objectName, null, null);
|
||||||
return createMultipartUploadResponse.result().uploadId();
|
return createMultipartUploadResponse.result().uploadId();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(MinioPlusErrorCode.CREATE_MULTIPART_UPLOAD_FAILED.getMessage()+":{}", e.getMessage(), e);
|
log.error("{}:{}", MinioPlusErrorCode.CREATE_MULTIPART_UPLOAD_FAILED.getMessage(), e.getMessage(), e);
|
||||||
throw new MinioPlusException(MinioPlusErrorCode.CREATE_MULTIPART_UPLOAD_FAILED);
|
throw new MinioPlusException(MinioPlusErrorCode.CREATE_MULTIPART_UPLOAD_FAILED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,7 +109,7 @@ public class MinioS3ClientImpl implements MinioS3Client {
|
|||||||
, objectName, uploadId, partArray, null, null);
|
, objectName, uploadId, partArray, null, null);
|
||||||
return objectWriteResponse != null;
|
return objectWriteResponse != null;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(MinioPlusErrorCode.COMPLETE_MULTIPART_FAILED.getMessage()+",uploadId:{},ObjectName:{},失败原因:{},", uploadId, objectName, e.getMessage(), e);
|
log.error("{},uploadId:{},ObjectName:{},失败原因:{},", MinioPlusErrorCode.COMPLETE_MULTIPART_FAILED.getMessage(), uploadId, objectName, e.getMessage(), e);
|
||||||
throw new MinioPlusException(MinioPlusErrorCode.COMPLETE_MULTIPART_FAILED);
|
throw new MinioPlusException(MinioPlusErrorCode.COMPLETE_MULTIPART_FAILED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -134,7 +135,7 @@ public class MinioS3ClientImpl implements MinioS3Client {
|
|||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// 查询分片失败,打印日志,返回空的分片信息
|
// 查询分片失败,打印日志,返回空的分片信息
|
||||||
log.error(MinioPlusErrorCode.LIST_PARTS_FAILED.getMessage()+":{}", e.getMessage());
|
log.error("{}:{}", MinioPlusErrorCode.LIST_PARTS_FAILED.getMessage(), e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
return listParts;
|
return listParts;
|
||||||
@ -157,7 +158,7 @@ public class MinioS3ClientImpl implements MinioS3Client {
|
|||||||
.extraQueryParams(queryParams)
|
.extraQueryParams(queryParams)
|
||||||
.build());
|
.build());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(MinioPlusErrorCode.CREATE_UPLOAD_URL_FAILED.getMessage()+":{}", e.getMessage(), e);
|
log.error("{}:{}", MinioPlusErrorCode.CREATE_UPLOAD_URL_FAILED.getMessage(), e.getMessage(), e);
|
||||||
throw new MinioPlusException(MinioPlusErrorCode.CREATE_UPLOAD_URL_FAILED);
|
throw new MinioPlusException(MinioPlusErrorCode.CREATE_UPLOAD_URL_FAILED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -178,7 +179,7 @@ public class MinioS3ClientImpl implements MinioS3Client {
|
|||||||
.extraQueryParams(reqParams)
|
.extraQueryParams(reqParams)
|
||||||
.build());
|
.build());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(MinioPlusErrorCode.CREATE_DOWNLOAD_URL_FAILED.getMessage()+":{}", e.getMessage(), e);
|
log.error("{}:{}", MinioPlusErrorCode.CREATE_DOWNLOAD_URL_FAILED.getMessage(), e.getMessage(), e);
|
||||||
throw new MinioPlusException(MinioPlusErrorCode.CREATE_DOWNLOAD_URL_FAILED);
|
throw new MinioPlusException(MinioPlusErrorCode.CREATE_DOWNLOAD_URL_FAILED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -199,7 +200,7 @@ public class MinioS3ClientImpl implements MinioS3Client {
|
|||||||
.extraQueryParams(reqParams)
|
.extraQueryParams(reqParams)
|
||||||
.build());
|
.build());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(MinioPlusErrorCode.CREATE_PREVIEW_URL_FAILED.getMessage()+":{}", e.getMessage(), e);
|
log.error("{}:{}", MinioPlusErrorCode.CREATE_PREVIEW_URL_FAILED.getMessage(), e.getMessage(), e);
|
||||||
throw new MinioPlusException(MinioPlusErrorCode.CREATE_PREVIEW_URL_FAILED);
|
throw new MinioPlusException(MinioPlusErrorCode.CREATE_PREVIEW_URL_FAILED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,7 +225,8 @@ public class MinioS3ClientImpl implements MinioS3Client {
|
|||||||
.contentType(contentType)
|
.contentType(contentType)
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
} catch (InsufficientDataException | InternalException | InvalidKeyException | IOException | NoSuchAlgorithmException | XmlParserException | ExecutionException | InterruptedException e) {
|
} catch (InsufficientDataException | InternalException | InvalidKeyException | IOException |
|
||||||
|
NoSuchAlgorithmException | XmlParserException | ExecutionException | InterruptedException e) {
|
||||||
log.error(MinioPlusErrorCode.WRITE_FAILED.getMessage(), e);
|
log.error(MinioPlusErrorCode.WRITE_FAILED.getMessage(), e);
|
||||||
throw new MinioPlusException(MinioPlusErrorCode.WRITE_FAILED);
|
throw new MinioPlusException(MinioPlusErrorCode.WRITE_FAILED);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,2 +0,0 @@
|
|||||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
|
||||||
org.liuxp.minioplus.s3.official.MinioS3ClientImpl
|
|
||||||
@ -0,0 +1 @@
|
|||||||
|
org.liuxp.minioplus.s3.official.MinioS3ClientImpl
|
||||||
@ -21,7 +21,8 @@
|
|||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
<version>${spring-boot2.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>me.liuxp</groupId>
|
<groupId>me.liuxp</groupId>
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
package org.liuxp.minioplus.extension.controller;
|
package org.liuxp.minioplus.extension.controller;
|
||||||
|
|
||||||
import cn.hutool.core.io.IoUtil;
|
import cn.hutool.core.io.IoUtil;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.liuxp.minioplus.api.StorageService;
|
import org.liuxp.minioplus.api.StorageService;
|
||||||
import org.liuxp.minioplus.api.model.vo.CompleteResultVo;
|
import org.liuxp.minioplus.api.model.vo.CompleteResultVo;
|
||||||
@ -20,49 +18,47 @@ import org.springframework.core.io.ClassPathResource;
|
|||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.util.FileCopyUtils;
|
import org.springframework.util.FileCopyUtils;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 对象存储标准接口定义
|
* 对象存储标准接口定义
|
||||||
* 本类的方法是给前端使用的方法
|
* 本类的方法是给前端使用的方法
|
||||||
|
*
|
||||||
* @author contact@liuxp.me
|
* @author contact@liuxp.me
|
||||||
* @since 2024/6/18
|
* @since 2024/6/18
|
||||||
*/
|
*/
|
||||||
@Controller
|
|
||||||
@RequestMapping("/storage")
|
|
||||||
@Tag(name = "MinIO Plus 接口")
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class StorageController {
|
@Controller
|
||||||
|
@RequestMapping(StorageWebAPI.ROOT_PATH)
|
||||||
|
public class StorageController implements StorageWebAPI {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重定向
|
* 重定向
|
||||||
*/
|
*/
|
||||||
private static final String REDIRECT_PREFIX = "redirect:";
|
private static final String REDIRECT_PREFIX = "redirect:";
|
||||||
|
|
||||||
/**
|
|
||||||
* 图标请求地址
|
|
||||||
*/
|
|
||||||
private static final String ICON_PATH = "/storage/icon/";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 存储引擎Service接口定义
|
* 存储引擎Service接口定义
|
||||||
*/
|
*/
|
||||||
@Resource
|
private final StorageService storageService;
|
||||||
private StorageService storageService;
|
|
||||||
|
public StorageController(StorageService storageService) {
|
||||||
|
this.storageService = storageService;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件预分片方法
|
* 文件预分片方法
|
||||||
* 在大文件上传时,为了防止前端重复计算文件MD5值,提供该方法
|
* 在大文件上传时,为了防止前端重复计算文件MD5值,提供该方法
|
||||||
|
*
|
||||||
* @param preShardingDTO 文件预分片入参DTO
|
* @param preShardingDTO 文件预分片入参DTO
|
||||||
* @return 预分片结果
|
* @return 预分片结果
|
||||||
*/
|
*/
|
||||||
@Operation(summary = "文件预分片")
|
@Override
|
||||||
@PostMapping("/upload/sharding")
|
|
||||||
@ResponseBody
|
|
||||||
public Response<FilePreShardingVo> sharding(@RequestBody @Validated PreShardingDTO preShardingDTO) {
|
public Response<FilePreShardingVo> sharding(@RequestBody @Validated PreShardingDTO preShardingDTO) {
|
||||||
|
|
||||||
FilePreShardingVo resultVo = storageService.sharding(preShardingDTO.getFileSize());
|
FilePreShardingVo resultVo = storageService.sharding(preShardingDTO.getFileSize());
|
||||||
@ -73,13 +69,12 @@ public class StorageController {
|
|||||||
/**
|
/**
|
||||||
* 上传任务初始化
|
* 上传任务初始化
|
||||||
* 上传前的预检查:秒传、分块上传和断点续传等特性均基于该方法实现
|
* 上传前的预检查:秒传、分块上传和断点续传等特性均基于该方法实现
|
||||||
|
*
|
||||||
* @param fileCheckDTO 文件预检查入参
|
* @param fileCheckDTO 文件预检查入参
|
||||||
* @return 检查结果
|
* @return 检查结果
|
||||||
*/
|
*/
|
||||||
@Operation(summary = "上传任务初始化")
|
@Override
|
||||||
@PostMapping("/upload/init")
|
public Response<FileCheckResultVo> init(FileCheckDTO fileCheckDTO) {
|
||||||
@ResponseBody
|
|
||||||
public Response<FileCheckResultVo> init(@RequestBody @Validated FileCheckDTO fileCheckDTO) {
|
|
||||||
|
|
||||||
// 取得当前登录用户信息
|
// 取得当前登录用户信息
|
||||||
String userId = UserHolder.get();
|
String userId = UserHolder.get();
|
||||||
@ -91,14 +86,13 @@ public class StorageController {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件上传完成
|
* 文件上传完成
|
||||||
|
*
|
||||||
* @param fileKey 文件KEY
|
* @param fileKey 文件KEY
|
||||||
* @param fileCompleteDTO 文件完成入参DTO
|
* @param fileCompleteDTO 文件完成入参DTO
|
||||||
* @return 是否成功
|
* @return 是否成功
|
||||||
*/
|
*/
|
||||||
@Operation(summary = "上传完成")
|
@Override
|
||||||
@PostMapping("/upload/complete/{fileKey}")
|
public Response<Object> complete(String fileKey, FileCompleteDTO fileCompleteDTO) {
|
||||||
@ResponseBody
|
|
||||||
public Response<Object> complete(@PathVariable("fileKey") String fileKey, @RequestBody FileCompleteDTO fileCompleteDTO) {
|
|
||||||
|
|
||||||
// 取得当前登录用户信息
|
// 取得当前登录用户信息
|
||||||
String userId = UserHolder.get();
|
String userId = UserHolder.get();
|
||||||
@ -112,12 +106,12 @@ public class StorageController {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件下载
|
* 文件下载
|
||||||
|
*
|
||||||
* @param fileKey 文件KEY
|
* @param fileKey 文件KEY
|
||||||
* @return 文件下载地址
|
* @return 文件下载地址
|
||||||
*/
|
*/
|
||||||
@Operation(summary = "文件下载")
|
@Override
|
||||||
@GetMapping("/download/{fileKey}")
|
public String download(String fileKey) {
|
||||||
public String download(@PathVariable String fileKey) {
|
|
||||||
|
|
||||||
// 取得当前登录用户信息
|
// 取得当前登录用户信息
|
||||||
String userId = UserHolder.get();
|
String userId = UserHolder.get();
|
||||||
@ -128,12 +122,12 @@ public class StorageController {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取图像
|
* 获取图像
|
||||||
|
*
|
||||||
* @param fileKey 文件KEY
|
* @param fileKey 文件KEY
|
||||||
* @return 原图地址
|
* @return 原图地址
|
||||||
*/
|
*/
|
||||||
@Operation(summary = "图片预览 - 原图")
|
@Override
|
||||||
@GetMapping("/image/{fileKey}")
|
public String previewOriginal(String fileKey) {
|
||||||
public String previewOriginal(@PathVariable String fileKey) {
|
|
||||||
|
|
||||||
// 取得当前登录用户信息
|
// 取得当前登录用户信息
|
||||||
String userId = UserHolder.get();
|
String userId = UserHolder.get();
|
||||||
@ -146,12 +140,12 @@ public class StorageController {
|
|||||||
* 文件预览
|
* 文件预览
|
||||||
* 当文件为图片时,返回图片的缩略图
|
* 当文件为图片时,返回图片的缩略图
|
||||||
* 当文件不是图片时,返回文件类型图标
|
* 当文件不是图片时,返回文件类型图标
|
||||||
|
*
|
||||||
* @param fileKey 文件KEY
|
* @param fileKey 文件KEY
|
||||||
* @return 缩略图地址
|
* @return 缩略图地址
|
||||||
*/
|
*/
|
||||||
@Operation(summary = "图片预览 - 缩略图")
|
@Override
|
||||||
@GetMapping("/preview/{fileKey}")
|
public String previewMedium(String fileKey) {
|
||||||
public String previewMedium(@PathVariable String fileKey) {
|
|
||||||
|
|
||||||
// 取得当前登录用户信息
|
// 取得当前登录用户信息
|
||||||
String userId = UserHolder.get();
|
String userId = UserHolder.get();
|
||||||
@ -168,14 +162,12 @@ public class StorageController {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据文件类型取得图标
|
* 根据文件类型取得图标
|
||||||
* @param response HttpServletResponse
|
*
|
||||||
* @param fileType 文件扩展名
|
* @param fileType 文件扩展名
|
||||||
*/
|
*/
|
||||||
@Operation(summary = "获取图标")
|
@Override
|
||||||
@GetMapping("/icon/{fileType}")
|
public void icon(String fileType) {
|
||||||
public void icon(HttpServletResponse response,@PathVariable String fileType) {
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// 根据文件后缀取得桶
|
// 根据文件后缀取得桶
|
||||||
String storageBucket = StorageBucketEnums.getBucketByFileSuffix(fileType);
|
String storageBucket = StorageBucketEnums.getBucketByFileSuffix(fileType);
|
||||||
|
|
||||||
@ -183,13 +175,12 @@ public class StorageController {
|
|||||||
|
|
||||||
byte[] bytes = FileCopyUtils.copyToByteArray(cpr.getInputStream());
|
byte[] bytes = FileCopyUtils.copyToByteArray(cpr.getInputStream());
|
||||||
|
|
||||||
response.setHeader("content-disposition", "inline");
|
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||||
response.setHeader("Content-Length", String.valueOf(bytes.length));
|
attr.getResponse().setHeader("content-disposition", "inline");
|
||||||
ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
|
attr.getResponse().setHeader("Content-Length", String.valueOf(bytes.length));
|
||||||
|
try (ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes)) {
|
||||||
IoUtil.copy(inputStream, response.getOutputStream());
|
IoUtil.copy(inputStream, attr.getResponse().getOutputStream());
|
||||||
inputStream.close();
|
}
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error(MinioPlusErrorCode.FILE_ICON_FAILED.getMessage(), e);
|
log.error(MinioPlusErrorCode.FILE_ICON_FAILED.getMessage(), e);
|
||||||
// 图标获取失败
|
// 图标获取失败
|
||||||
@ -1,2 +0,0 @@
|
|||||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
|
||||||
org.liuxp.minioplus.common.config.MinioPlusAutoConfiguration
|
|
||||||
@ -0,0 +1 @@
|
|||||||
|
org.liuxp.minioplus.common.config.MinioPlusAutoConfiguration
|
||||||
@ -15,11 +15,21 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>17</maven.compiler.source>
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
<maven.compiler.target>17</maven.compiler.target>
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
|
<!--<maven.compiler.compilerVersion>17</maven.compiler.compilerVersion>-->
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
<version>${spring-boot3.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>jakarta.servlet</groupId>
|
||||||
|
<artifactId>jakarta.servlet-api</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>me.liuxp</groupId>
|
<groupId>me.liuxp</groupId>
|
||||||
<artifactId>minio-plus-extension</artifactId>
|
<artifactId>minio-plus-extension</artifactId>
|
||||||
|
|||||||
@ -0,0 +1,191 @@
|
|||||||
|
package org.liuxp.minioplus.extension.controller;
|
||||||
|
|
||||||
|
import cn.hutool.core.io.IoUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.liuxp.minioplus.api.StorageService;
|
||||||
|
import org.liuxp.minioplus.api.model.vo.CompleteResultVo;
|
||||||
|
import org.liuxp.minioplus.api.model.vo.FileCheckResultVo;
|
||||||
|
import org.liuxp.minioplus.api.model.vo.FilePreShardingVo;
|
||||||
|
import org.liuxp.minioplus.common.enums.MinioPlusErrorCode;
|
||||||
|
import org.liuxp.minioplus.common.enums.StorageBucketEnums;
|
||||||
|
import org.liuxp.minioplus.common.exception.MinioPlusException;
|
||||||
|
import org.liuxp.minioplus.extension.context.Response;
|
||||||
|
import org.liuxp.minioplus.extension.context.UserHolder;
|
||||||
|
import org.liuxp.minioplus.extension.dto.FileCheckDTO;
|
||||||
|
import org.liuxp.minioplus.extension.dto.FileCompleteDTO;
|
||||||
|
import org.liuxp.minioplus.extension.dto.PreShardingDTO;
|
||||||
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.util.FileCopyUtils;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.context.request.RequestContextHolder;
|
||||||
|
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对象存储标准接口定义
|
||||||
|
* 本类的方法是给前端使用的方法
|
||||||
|
*
|
||||||
|
* @author contact@liuxp.me
|
||||||
|
* @since 2024/6/18
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Controller
|
||||||
|
@RequestMapping(StorageWebAPI.ROOT_PATH)
|
||||||
|
public class StorageController implements StorageWebAPI {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重定向
|
||||||
|
*/
|
||||||
|
private static final String REDIRECT_PREFIX = "redirect:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 存储引擎Service接口定义
|
||||||
|
*/
|
||||||
|
private final StorageService storageService;
|
||||||
|
|
||||||
|
public StorageController(StorageService storageService) {
|
||||||
|
this.storageService = storageService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件预分片方法
|
||||||
|
* 在大文件上传时,为了防止前端重复计算文件MD5值,提供该方法
|
||||||
|
*
|
||||||
|
* @param preShardingDTO 文件预分片入参DTO
|
||||||
|
* @return 预分片结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Response<FilePreShardingVo> sharding(@RequestBody @Validated PreShardingDTO preShardingDTO) {
|
||||||
|
|
||||||
|
FilePreShardingVo resultVo = storageService.sharding(preShardingDTO.getFileSize());
|
||||||
|
|
||||||
|
return Response.success(resultVo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传任务初始化
|
||||||
|
* 上传前的预检查:秒传、分块上传和断点续传等特性均基于该方法实现
|
||||||
|
*
|
||||||
|
* @param fileCheckDTO 文件预检查入参
|
||||||
|
* @return 检查结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Response<FileCheckResultVo> init(FileCheckDTO fileCheckDTO) {
|
||||||
|
|
||||||
|
// 取得当前登录用户信息
|
||||||
|
String userId = UserHolder.get();
|
||||||
|
|
||||||
|
FileCheckResultVo resultVo = storageService.init(fileCheckDTO.getFileMd5(), fileCheckDTO.getFullFileName(), fileCheckDTO.getFileSize(), fileCheckDTO.getIsPrivate(), userId);
|
||||||
|
|
||||||
|
return Response.success(resultVo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件上传完成
|
||||||
|
*
|
||||||
|
* @param fileKey 文件KEY
|
||||||
|
* @param fileCompleteDTO 文件完成入参DTO
|
||||||
|
* @return 是否成功
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Response<Object> complete(String fileKey, FileCompleteDTO fileCompleteDTO) {
|
||||||
|
|
||||||
|
// 取得当前登录用户信息
|
||||||
|
String userId = UserHolder.get();
|
||||||
|
|
||||||
|
// 打印调试日志
|
||||||
|
log.debug("合并文件开始fileKey=" + fileKey + ",partMd5List=" + fileCompleteDTO.getPartMd5List());
|
||||||
|
CompleteResultVo completeResultVo = storageService.complete(fileKey, fileCompleteDTO.getPartMd5List(), userId);
|
||||||
|
|
||||||
|
return Response.success(completeResultVo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件下载
|
||||||
|
*
|
||||||
|
* @param fileKey 文件KEY
|
||||||
|
* @return 文件下载地址
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String download(String fileKey) {
|
||||||
|
|
||||||
|
// 取得当前登录用户信息
|
||||||
|
String userId = UserHolder.get();
|
||||||
|
|
||||||
|
// 取得文件读取路径
|
||||||
|
return REDIRECT_PREFIX + storageService.download(fileKey, userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取图像
|
||||||
|
*
|
||||||
|
* @param fileKey 文件KEY
|
||||||
|
* @return 原图地址
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String previewOriginal(String fileKey) {
|
||||||
|
|
||||||
|
// 取得当前登录用户信息
|
||||||
|
String userId = UserHolder.get();
|
||||||
|
|
||||||
|
// 取得文件读取路径
|
||||||
|
return REDIRECT_PREFIX + storageService.image(fileKey, userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件预览
|
||||||
|
* 当文件为图片时,返回图片的缩略图
|
||||||
|
* 当文件不是图片时,返回文件类型图标
|
||||||
|
*
|
||||||
|
* @param fileKey 文件KEY
|
||||||
|
* @return 缩略图地址
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String previewMedium(String fileKey) {
|
||||||
|
|
||||||
|
// 取得当前登录用户信息
|
||||||
|
String userId = UserHolder.get();
|
||||||
|
|
||||||
|
String url = storageService.preview(fileKey, userId);
|
||||||
|
if (url.length() < 10) {
|
||||||
|
// 当返回值为文件类型时,取得图标
|
||||||
|
url = ICON_PATH + url;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取得文件读取路径
|
||||||
|
return REDIRECT_PREFIX + url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据文件类型取得图标
|
||||||
|
*
|
||||||
|
* @param fileType 文件扩展名
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void icon(String fileType) {
|
||||||
|
try {
|
||||||
|
// 根据文件后缀取得桶
|
||||||
|
String storageBucket = StorageBucketEnums.getBucketByFileSuffix(fileType);
|
||||||
|
|
||||||
|
ClassPathResource cpr = new ClassPathResource(storageBucket + ".png");
|
||||||
|
|
||||||
|
byte[] bytes = FileCopyUtils.copyToByteArray(cpr.getInputStream());
|
||||||
|
|
||||||
|
ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||||
|
attr.getResponse().setHeader("content-disposition", "inline");
|
||||||
|
attr.getResponse().setHeader("Content-Length", String.valueOf(bytes.length));
|
||||||
|
try (ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes)) {
|
||||||
|
IoUtil.copy(inputStream, attr.getResponse().getOutputStream());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(MinioPlusErrorCode.FILE_ICON_FAILED.getMessage(), e);
|
||||||
|
// 图标获取失败
|
||||||
|
throw new MinioPlusException(MinioPlusErrorCode.FILE_ICON_FAILED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -22,6 +22,8 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter</artifactId>
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
<version>${spring-boot.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>me.liuxp</groupId>
|
<groupId>me.liuxp</groupId>
|
||||||
|
|||||||
@ -1,2 +0,0 @@
|
|||||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
|
||||||
org.liuxp.minioplus.common.config.MinioPlusAutoConfiguration
|
|
||||||
@ -0,0 +1 @@
|
|||||||
|
org.liuxp.minioplus.common.config.MinioPlusAutoConfiguration
|
||||||
49
pom.xml
49
pom.xml
@ -50,9 +50,13 @@
|
|||||||
<maven.compiler.target>1.8</maven.compiler.target>
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
<maven-source-plugin.version>3.0.1</maven-source-plugin.version>
|
<maven-source-plugin.version>3.0.1</maven-source-plugin.version>
|
||||||
<revision>0.1.5</revision>
|
<revision>0.1.5</revision>
|
||||||
<spring-boot.version>2.7.18</spring-boot.version>
|
<spring-boot2.version>2.7.18</spring-boot2.version>
|
||||||
|
<spring-boot3.version>3.3.2</spring-boot3.version>
|
||||||
|
<spring-boot.version>${spring-boot2.version}</spring-boot.version>
|
||||||
<mybatisplus.version>3.5.7</mybatisplus.version>
|
<mybatisplus.version>3.5.7</mybatisplus.version>
|
||||||
|
<mysql-connector-j.version>8.0.33</mysql-connector-j.version>
|
||||||
<lombok.version>1.18.32</lombok.version>
|
<lombok.version>1.18.32</lombok.version>
|
||||||
|
<jakarta-servlet-api.version>6.0.0</jakarta-servlet-api.version>
|
||||||
<hutool.version>5.8.28</hutool.version>
|
<hutool.version>5.8.28</hutool.version>
|
||||||
<knife4j.version>4.4.0</knife4j.version>
|
<knife4j.version>4.4.0</knife4j.version>
|
||||||
<swagger.version>2.2.8</swagger.version>
|
<swagger.version>2.2.8</swagger.version>
|
||||||
@ -63,24 +67,44 @@
|
|||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- spring-boot-dependencies -->
|
<!-- mybatis-plus -->
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-dependencies</artifactId>
|
|
||||||
<version>${spring-boot.version}</version>
|
|
||||||
<type>pom</type>
|
|
||||||
<scope>import</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.baomidou</groupId>
|
<groupId>com.baomidou</groupId>
|
||||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||||
<version>${mybatisplus.version}</version>
|
<version>${mybatisplus.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
|
||||||
|
<version>${mybatisplus.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-j</artifactId>
|
||||||
|
<version>${mysql-connector-j.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>jakarta.servlet</groupId>
|
||||||
|
<artifactId>jakarta.servlet-api</artifactId>
|
||||||
|
<version>${jakarta-servlet-api.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
<version>${lombok.version}</version>
|
<version>${lombok.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!--<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-api</artifactId>
|
||||||
|
<version>1.7.36</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-log4j12</artifactId>
|
||||||
|
<version>1.7.36</version>
|
||||||
|
</dependency>-->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.hutool</groupId>
|
<groupId>cn.hutool</groupId>
|
||||||
<artifactId>hutool-all</artifactId>
|
<artifactId>hutool-all</artifactId>
|
||||||
@ -103,13 +127,6 @@
|
|||||||
<artifactId>swagger-annotations</artifactId>
|
<artifactId>swagger-annotations</artifactId>
|
||||||
<version>${swagger.version}</version>
|
<version>${swagger.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- mybatis -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.baomidou</groupId>
|
|
||||||
<artifactId>mybatis-plus</artifactId>
|
|
||||||
<version>${mybatisplus.version}</version>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
<!-- minio -->
|
<!-- minio -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.minio</groupId>
|
<groupId>io.minio</groupId>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user