1
目 标
实现阿里云oss,ftp和本地文件存储的功能,通过配置方式选择启用不同的功能
2
接 口
在接口里添加上传,删除,下载以及远程访问方法
public interface FileClient {/*** 上传文件** @param inputStream 文件流* @param path 相对路径* @return 完整路径,即 HTTP 访问地址*/String upload(InputStream inputStream, String path);/*** 删除文件** @param path 相对路径*/void delete(String path);/*** 获得文件的内容** @param path 相对路径* @return 文件的内容*/byte[] getContent(String path);/*** 获得文件的签名地址** @param path 相对路径* @return 文件的内容*/String getSignedUrl(String path);ClinetTypeEnum getClientType();}
public enum ClinetTypeEnum {//ftpFTP("ftp"),//ossOSS("oss"),//localLOCAL("local");private final String type;ClinetTypeEnum(String type) {this.type = type;}public String getType() {return type;}}
public interface FileClientConfig {}
3
ftp实现
在file.ftp.enable的情况下生成FtpFileConfig,在生成FtpFileConfig的情况下生成FtpFileClient
通过配置是否启用ftp,可选择性的生成FtpFileClient
ftp库由hutool依赖提供
getSignedUrl方法可通过实际情况自定义
@Component@ConditionalOnBean(value = FtpFileConfig.class)@Log4j2public class FtpFileClient implements FileClient {private final FtpFileConfig ftpFileConfig;private final Ftp ftp;@Autowiredpublic FtpFileClient(FtpFileConfig ftpFileConfig) {this.ftpFileConfig = ftpFileConfig;ftp = new Ftp(ftpFileConfig.getIp(), ftpFileConfig.getPort(), ftpFileConfig.getUsername(), ftpFileConfig.getPassword());ftp.setMode(FtpMode.Passive);}@Overridepublic String upload(InputStream inputStream, String path) {String filePath = getFilePath(path);String fileName = FileUtil.getName(filePath);String dir = StrUtil.removeSuffix(filePath, fileName);ftp.reconnectIfTimeout();boolean success = ftp.upload(dir, fileName, inputStream);if (!success) {throw new FtpException(StrUtil.format("上传文件到目标目录 ({}) 失败", filePath));}return null;}@Overridepublic void delete(String path) {String filePath = getFilePath(path);ftp.reconnectIfTimeout();ftp.delFile(filePath);}@Overridepublic byte[] getContent(String path) {String filePath = getFilePath(path);String fileName = FileUtil.getName(filePath);String dir = StrUtil.removeSuffix(filePath, fileName);ByteArrayOutputStream out = new ByteArrayOutputStream();ftp.reconnectIfTimeout();ftp.download(dir, fileName, out);return out.toByteArray();}@Overridepublic String getSignedUrl(String path) {return null;}private String getFilePath(String path) {return ftpFileConfig.getBasePath() + path;}@Overridepublic ClinetTypeEnum getClientType() {return ClinetTypeEnum.FTP;}}
@Data@Component@ConditionalOnProperty(value = "file.ftp.enable", havingValue = "true")public class FtpFileConfig implements FileClientConfig {@Value("${file.ftp.ip}")private String ip;@Value("${file.ftp.port}")private int port;@Value("${file.ftp.username}")private String username;@Value("${file.ftp.password}")private String password;@Value("${file.ftp.basePath}")private String basePath;}
4
阿里云oss实现
在file.oss.enable的情况下生成OssFileConfig,在生成FtpFileConfig的情况下生成OssFileClient
通过配置是否启用oss,可选择性的生成OssFileClient
oss库由阿里云sdk提供
@Component@ConditionalOnBean(value = OssFileConfig.class)@Log4j2@Datapublic class OssFileClient implements FileClient {private final OssFileConfig ossFileConfig;private final OSSClient inClient;private final OSSClient outClient;@Autowiredpublic OssFileClient(OssFileConfig ossFileConfig) {this.ossFileConfig = ossFileConfig;this.inClient = new OSSClient(ossFileConfig.getInEndpoint(), ossFileConfig.getAccessKeyId(), ossFileConfig.getAccessKeySecret());this.outClient = new OSSClient(ossFileConfig.getEndpoint(), ossFileConfig.getAccessKeyId(), ossFileConfig.getAccessKeySecret());}@Overridepublic String upload(InputStream inputStream, String path) {OSSClient client = getInClient();String bucket = ossFileConfig.getBucket();client.putObject(bucket, path, inputStream);//使用内网地址上传,返回地址改为外网地址String url = ossFileConfig.getHttpBase() + path;log.info("[{}] OSS上传成功,返回签名URL: {}", Thread.currentThread().getName(), url);return url;}@Overridepublic void delete(String path) {OSSClient client = getInClient();client.deleteObject(ossFileConfig.getBucket(), path);}@Overridepublic byte[] getContent(String path) {OSSClient ossClient = getInClient();OSSObject ossObject = ossClient.getObject(ossFileConfig.getBucket(), path);return IoUtil.readBytes(ossObject.getObjectContent());}@Overridepublic String getSignedUrl(String path) {Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000L);String bucket = ossFileConfig.getBucket();if (path.startsWith(ossFileConfig.getHttpBase())) {path = path.replace(ossFileConfig.getHttpBase(), "");}URL url = getOutClient().generatePresignedUrl(bucket, path, expiration);return url.toString();}@Overridepublic ClinetTypeEnum getClientType() {return ClinetTypeEnum.OSS;}}
@Data@Component@ConditionalOnProperty(value = "file.oss.enable", havingValue = "true")public class OssFileConfig implements FileClientConfig {@Value("${file.oss.bucket}")private String bucket;@Value("${file.oss.accessKeyId}")private String accessKeyId;@Value("${file.oss.accessKeySecret}")private String accessKeySecret;@Value("${file.oss.endpoint}")private String endpoint;@Value("${file.oss.httpBase}")private String httpBase;@Value("${file.oss.inEndpoint}")private String inEndpoint;@Value("${file.oss.inHttpBase}")private String inHttpBase;}
5
本地存储实现
在file.local.enable的情况下生成LocalFileConfig,在生成LocalFileConfig的情况下生成LocalFileClient
通过配置是否启用local,可选择性的生成LocalFileClient
文件将会保存在服务器本地
getSignedUrl方法可通过实际情况自定义,如果不需要签名,也可以直接使用nginx代理地址
@Component@ConditionalOnBean(value = LocalFileConfig.class)@Log4j2public class LocalFileClient implements FileClient {private final LocalFileConfig localFileConfig;@Autowiredpublic LocalFileClient(LocalFileConfig localFileConfig) {this.localFileConfig = localFileConfig;}@Overridepublic String upload(InputStream inputStream, String path) {String filePath = getFilePath(path);FileUtil.writeFromStream(inputStream, filePath);return null;}@Overridepublic void delete(String path) {String filePath = getFilePath(path);FileUtil.del(filePath);}@Overridepublic byte[] getContent(String path) {String filePath = getFilePath(path);return FileUtil.readBytes(filePath);}@Overridepublic String getSignedUrl(String path) {return null;}private String getFilePath(String path) {return localFileConfig.getBasePath() + path;}@Overridepublic ClinetTypeEnum getClientType() {return ClinetTypeEnum.LOCAL;}}
@Data@Component@ConditionalOnProperty(value = "file.local.enable", havingValue = "true")public class LocalFileConfig implements FileClientConfig {@Value("${file.local.basePath}")private String basePath;}
6
使 用
在配置文件里配置不同存储方式的配置和是否启用
file:local:enable: truebasePath: /temp/oss:enable: truebucket: 1accessKeyId: 1accessKeySecret: 1endpoint: http://oss-cn-hangzhou.aliyuncs.comhttpBase: http://1.oss-cn-hangzhou.aliyuncs.com/inEndpoint: http://oss-cn-hangzhou-internal.aliyuncs.cominHttpBase: http://1.oss-cn-hangzhou-internal.aliyuncs.com/ftp:enable: trueip: 192.168.1.1port: 7763username: 1password: 2basePath: /file
在代码里注入FileClient后即可调用不同的功能
@Autowiredprivate List<FileClient> fileClients;
1066

被折叠的 条评论
为什么被折叠?



