新增文件上传功能,支持阿里云、本地文件上传
This commit is contained in:
parent
41da694227
commit
fd1747c429
|
@ -0,0 +1,18 @@
|
|||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<groupId>net.maku</groupId>
|
||||
<artifactId>fast-boot</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>fast-boot-api</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,67 @@
|
|||
package net.maku.api.module.storage;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* 存储服务
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public interface StorageService {
|
||||
/**
|
||||
* 文件路径
|
||||
* @param prefix 前缀
|
||||
* @param suffix 后缀
|
||||
* @return 返回上传路径
|
||||
*/
|
||||
default String getPath(String prefix, String suffix) {
|
||||
//生成uuid
|
||||
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
|
||||
//文件路径
|
||||
SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
|
||||
String path = df.format(new Date()) + "/" + uuid;
|
||||
|
||||
if(StringUtils.hasText(prefix)){
|
||||
path = prefix + "/" + path;
|
||||
}
|
||||
|
||||
return path + "." + suffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
* @param data 文件字节数组
|
||||
* @param path 文件路径,包含文件名
|
||||
* @return 返回http地址
|
||||
*/
|
||||
String upload(byte[] data, String path);
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
* @param data 文件字节数组
|
||||
* @param suffix 后缀
|
||||
* @return 返回http地址
|
||||
*/
|
||||
String uploadSuffix(byte[] data, String suffix);
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
* @param inputStream 字节流
|
||||
* @param path 文件路径,包含文件名
|
||||
* @return 返回http地址
|
||||
*/
|
||||
String upload(InputStream inputStream, String path);
|
||||
|
||||
/**
|
||||
* 文件上传
|
||||
* @param inputStream 字节流
|
||||
* @param suffix 后缀
|
||||
* @return 返回http地址
|
||||
*/
|
||||
String uploadSuffix(InputStream inputStream, String suffix);
|
||||
}
|
|
@ -15,6 +15,15 @@
|
|||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.maku</groupId>
|
||||
<artifactId>fast-boot-api</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.aliyun.oss</groupId>
|
||||
<artifactId>aliyun-sdk-oss</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.whvcse</groupId>
|
||||
<artifactId>easy-captcha</artifactId>
|
||||
</dependency>
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package net.maku.storage.config;
|
||||
|
||||
import net.maku.storage.enums.StorageTypeEnum;
|
||||
import net.maku.storage.properties.LocalStorageProperties;
|
||||
import net.maku.storage.properties.StorageProperties;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* 本地资源映射配置
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnProperty(prefix = "storage", value = "enabled")
|
||||
public class LocalResourceConfiguration implements WebMvcConfigurer {
|
||||
@Resource
|
||||
private StorageProperties properties;
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
// 如果不是本地存储,则返回
|
||||
if(properties.getConfig().getType() != StorageTypeEnum.LOCAL){
|
||||
return;
|
||||
}
|
||||
|
||||
LocalStorageProperties local = properties.getLocal();
|
||||
registry.addResourceHandler("/" + local.getUrl() + "/**")
|
||||
.addResourceLocations("file:" + local.getPath() + "/");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package net.maku.storage.config;
|
||||
|
||||
import net.maku.api.module.storage.StorageService;
|
||||
import net.maku.storage.enums.StorageTypeEnum;
|
||||
import net.maku.storage.properties.StorageProperties;
|
||||
import net.maku.storage.service.AliyunStorageService;
|
||||
import net.maku.storage.service.LocalStorageService;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* 存储配置文件
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(StorageProperties.class)
|
||||
@ConditionalOnProperty(prefix = "storage", value = "enabled")
|
||||
public class StorageConfiguration {
|
||||
|
||||
@Bean
|
||||
public StorageService storageService(StorageProperties properties){
|
||||
if(properties.getConfig().getType() == StorageTypeEnum.LOCAL){
|
||||
return new LocalStorageService(properties);
|
||||
}else if(properties.getConfig().getType() == StorageTypeEnum.ALIYUN){
|
||||
return new AliyunStorageService(properties);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package net.maku.storage.enums;
|
||||
|
||||
/**
|
||||
* 存储类型枚举
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public enum StorageTypeEnum {
|
||||
/**
|
||||
* 本地
|
||||
*/
|
||||
LOCAL,
|
||||
/**
|
||||
* 阿里云
|
||||
*/
|
||||
ALIYUN;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package net.maku.storage.properties;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 阿里云存储配置项
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
public class AliyunStorageProperties {
|
||||
private String endPoint;
|
||||
private String accessKeyId;
|
||||
private String accessKeySecret;
|
||||
private String bucketName;
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package net.maku.storage.properties;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 本地存储配置项
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
public class LocalStorageProperties {
|
||||
/**
|
||||
* 本地存储路径
|
||||
*/
|
||||
private String path;
|
||||
/**
|
||||
* 资源起始路径
|
||||
*/
|
||||
private String url = "upload";
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package net.maku.storage.properties;
|
||||
|
||||
import lombok.Data;
|
||||
import net.maku.storage.enums.StorageTypeEnum;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* 存储配置项
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
@Data
|
||||
@ConfigurationProperties(prefix = "storage")
|
||||
public class StorageProperties {
|
||||
/**
|
||||
* 是否开启存储
|
||||
*/
|
||||
private boolean enabled;
|
||||
/**
|
||||
* 通用配置项
|
||||
*/
|
||||
private StorageConfig config;
|
||||
/**
|
||||
* 本地配置项
|
||||
*/
|
||||
private LocalStorageProperties local;
|
||||
/**
|
||||
* 阿里云配置项
|
||||
*/
|
||||
private AliyunStorageProperties aliyun;
|
||||
|
||||
@Data
|
||||
public static class StorageConfig{
|
||||
/**
|
||||
* 访问域名
|
||||
*/
|
||||
private String domain;
|
||||
/**
|
||||
* 配置路径前缀
|
||||
*/
|
||||
private String prefix;
|
||||
/**
|
||||
* 存储类型
|
||||
*/
|
||||
private StorageTypeEnum type;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package net.maku.storage.service;
|
||||
|
||||
import com.aliyun.oss.OSS;
|
||||
import com.aliyun.oss.OSSClientBuilder;
|
||||
import net.maku.api.module.storage.StorageService;
|
||||
import net.maku.framework.common.exception.FastException;
|
||||
import net.maku.storage.properties.StorageProperties;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* 阿里云存储
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public class AliyunStorageService implements StorageService {
|
||||
private final StorageProperties properties;
|
||||
|
||||
public AliyunStorageService(StorageProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String upload(byte[] data, String path) {
|
||||
return upload(new ByteArrayInputStream(data), path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String uploadSuffix(byte[] data, String suffix) {
|
||||
return upload(data, getPath(properties.getConfig().getPrefix(), suffix));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String upload(InputStream inputStream, String path) {
|
||||
OSS client = new OSSClientBuilder().build(properties.getAliyun().getEndPoint(),
|
||||
properties.getAliyun().getAccessKeyId(), properties.getAliyun().getAccessKeySecret());
|
||||
try {
|
||||
client.putObject(properties.getAliyun().getBucketName(), path, inputStream);
|
||||
}catch (Exception e){
|
||||
throw new FastException("上传文件失败:", e);
|
||||
} finally {
|
||||
if (client != null) {
|
||||
client.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
return properties.getConfig().getDomain() + "/" + path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String uploadSuffix(InputStream inputStream, String suffix) {
|
||||
return upload(inputStream, getPath(properties.getConfig().getPrefix(), suffix));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package net.maku.storage.service;
|
||||
|
||||
import net.maku.api.module.storage.StorageService;
|
||||
import net.maku.framework.common.exception.FastException;
|
||||
import net.maku.storage.properties.StorageProperties;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
|
||||
/**
|
||||
* 本地存储
|
||||
*
|
||||
* @author 阿沐 babamu@126.com
|
||||
*/
|
||||
public class LocalStorageService implements StorageService {
|
||||
private final StorageProperties properties;
|
||||
|
||||
public LocalStorageService(StorageProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String upload(byte[] data, String path) {
|
||||
return upload(new ByteArrayInputStream(data), path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String uploadSuffix(byte[] data, String suffix) {
|
||||
return upload(data, getPath(properties.getConfig().getPrefix(), suffix));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String upload(InputStream inputStream, String path) {
|
||||
|
||||
try {
|
||||
File file = new File(properties.getLocal().getPath() + File.separator + path);
|
||||
|
||||
// 没有目录,则自动创建目录
|
||||
File parent = file.getParentFile();
|
||||
if (parent != null && !parent.mkdirs() && !parent.isDirectory()) {
|
||||
throw new IOException("Directory '" + parent + "' could not be created");
|
||||
}
|
||||
|
||||
FileCopyUtils.copy(inputStream, Files.newOutputStream(file.toPath()));
|
||||
} catch (Exception e) {
|
||||
throw new FastException("上传文件失败:", e);
|
||||
}
|
||||
|
||||
return properties.getConfig().getDomain() + "/" + properties.getLocal().getUrl() + "/" + path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String uploadSuffix(InputStream inputStream, String suffix) {
|
||||
return upload(inputStream, getPath(properties.getConfig().getPrefix(), suffix));
|
||||
}
|
||||
}
|
|
@ -8,4 +8,5 @@ auth:
|
|||
- /swagger-ui.html
|
||||
- /swagger-ui/**
|
||||
- /doc.html
|
||||
- /sys/oauth/captcha
|
||||
- /sys/oauth/captcha
|
||||
- /upload/**
|
|
@ -21,6 +21,18 @@ spring:
|
|||
max-file-size: 1024MB
|
||||
max-request-size: 1024MB
|
||||
|
||||
storage:
|
||||
enabled: true
|
||||
config:
|
||||
# 存储类型:local、aliyun
|
||||
type: local
|
||||
# 访问域名
|
||||
domain: http://localhost:8080
|
||||
# 配置访问前缀
|
||||
prefix:
|
||||
local:
|
||||
# 本地上传路径
|
||||
path: D://upload
|
||||
|
||||
mybatis-plus:
|
||||
mapper-locations: classpath*:/mapper/**/*.xml
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package net.maku;
|
||||
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import net.maku.api.module.storage.StorageService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
|
||||
@SpringBootTest
|
||||
public class FileUploadTest {
|
||||
@Autowired
|
||||
private StorageService storageService;
|
||||
|
||||
@Test
|
||||
public void uploadTest() throws Exception{
|
||||
byte[] data = IoUtil.readBytes(Files.newInputStream(new File("D://upload//1.png").toPath()));
|
||||
String url = storageService.uploadSuffix(data, "png");
|
||||
System.out.println(url);
|
||||
}
|
||||
|
||||
}
|
9
pom.xml
9
pom.xml
|
@ -17,8 +17,9 @@
|
|||
</parent>
|
||||
|
||||
<modules>
|
||||
<module>fast-boot-system</module>
|
||||
<module>fast-boot-new</module>
|
||||
<module>fast-boot-system</module>
|
||||
<module>fast-boot-api</module>
|
||||
<module>fast-framework</module>
|
||||
<module>fast-server</module>
|
||||
</modules>
|
||||
|
@ -34,6 +35,7 @@
|
|||
<security.oauth2.version>2.3.8.RELEASE</security.oauth2.version>
|
||||
<captcha.version>1.6.2</captcha.version>
|
||||
<mapstruct.version>1.4.2.Final</mapstruct.version>
|
||||
<aliyun.oss.version>3.8.0</aliyun.oss.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
@ -103,6 +105,11 @@
|
|||
<artifactId>mapstruct-processor</artifactId>
|
||||
<version>${mapstruct.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.aliyun.oss</groupId>
|
||||
<artifactId>aliyun-sdk-oss</artifactId>
|
||||
<version>${aliyun.oss.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user