FTP 存储
简介
各个系统的文件在存放在文件系统里的时候,首先保存在关系型数据库里,方便查找和查询。
y9 提供了一种数据库存储方式: risenet-y9boot-support-file-jpaRepository
Y9 提供了以下 FTP 存储调用模块:
risenet-y9boot-support-fileService-FTP
提供了下载的 REST 方法,其中 realStoreFileName 即关系型数据库中的主键 ID。
http://ip:端口/(工程上下文)/s/{realStoreFileName}
http://ip:端口/(工程上下文)/files/{realStoreFileName}
http://ip:端口/(工程上下文)/s?realStoreFileName=XXXX
例如:
- https://demo-api.youshengyun.com/platform/files/7f21d7927a034ab6ade47b8511292264.sql
- https://demo-api.youshengyun.com/platform/s/7f21d7927a034ab6ade47b8511292264
- https://demo-api.youshengyun.com/platform/s?realStoreFileName=7f21d7927a034ab6ade47b8511292264
以上3种方式都可以下载上传的文件。
功能引用
(1)修改 pom.xml
将本公司的私服仓库地址添加到 pom.xml 文件中。
xml
<repositories>
<repository>
<id>y9-internet-repo</id>
<url>https://svn.youshengyun.com:9900/nexus/repository/maven-public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<!-- <updatePolicy>always</updatePolicy> -->
<!-- always,daily(default),interval:XXX,never -->
</snapshots>
</repository>
</repositories>
(2)将 risenet-y9boot-support-file-service-ftp 添加到 pom.xml 的依赖列表里.
<dependency>
<groupId>net.risesoft</groupId>
<artifactId>risenet-y9boot-support-file-service-ftp</artifactId>
<version>[最新版本]</version>
</dependency>
(3)修改属性文件 application.properties
properties
#数字底座的公共数据源配置有初始化,可排除自动配置
spring.autoconfigure.exclude[0]=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
spring.autoconfigure.exclude[1]=org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
#文件相关表信息需要的数据源信息,需要配置为数字底座的公共数据源
spring.datasource.druid.y9-public.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.y9-public.url=jdbc:mysql://localhost:3306/y9_public?serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&useUnicode=true&characterEncoding=utf-8&rewriteBatchedStatements=true&useCompression=true&useSSL=false&allowPublicKeyRetrieval=true
spring.datasource.druid.y9-public.username=root
spring.datasource.druid.y9-public.password=111111
spring.datasource.druid.y9-public.initialSize=1
spring.datasource.druid.y9-public.maxActive=20
spring.datasource.druid.y9-public.maxPoolPreparedStatementPerConnectionSize=100
spring.datasource.druid.y9-public.maxWait=60000
spring.datasource.druid.y9-public.minEvictableIdleTimeMillis=300000
spring.datasource.druid.y9-public.minIdle=1
spring.datasource.druid.y9-public.poolPreparedStatements=true
spring.datasource.druid.y9-public.testOnBorrow=false
spring.datasource.druid.y9-public.testOnReturn=false
spring.datasource.druid.y9-public.testWhileIdle=true
spring.datasource.druid.y9-public.timeBetweenEvictionRunsMillis=60000
spring.datasource.druid.y9-public.useGlobalDataSourceStat=true
spring.datasource.druid.y9-public.validationQuery=SELECT 1 FROM DUAL
#是否对文件名 base64 编码
y9.feature.file.base64FileName=false
#是否用对称加密算法 AES 加密文件内容
y9.feature.file.encryptionFileContent=false
#当存储文件容量不足时,新挂载的文件夹地址,默认为空
#y9.feature.file.prefix=
#是否启用
y9.feature.file.ftp.enabled=true
y9.feature.file.ftp.host=localhost
y9.feature.file.ftp.port=21
y9.feature.file.ftp.username=y9admin
y9.feature.file.ftp.password=111111
y9.feature.file.ftp.blockWhenExhausted=true
y9.feature.file.ftp.bufferSize=10240
y9.feature.file.ftp.connectTimeOut=50000
y9.feature.file.ftp.controlEncoding=UTF-8
y9.feature.file.ftp.dataTimeout=1200000
y9.feature.file.ftp.fileType=2
y9.feature.file.ftp.maxIdle=10
y9.feature.file.ftp.maxTotal=50
y9.feature.file.ftp.minIdle=2
y9.feature.file.ftp.maxWaitMillis=5400000
y9.feature.file.ftp.testOnBorrow=true
y9.feature.file.ftp.testOnCreate=true
y9.feature.file.ftp.testOnReturn=true
y9.feature.file.ftp.testWhileIdle=true
y9.feature.file.ftp.useEPSVwithIPv4=false
y9.feature.file.ftp.passiveMode=true
#数字底座文件上传的包的需要扫描的包路径,不能更改
y9.feature.jpa.packagesToScanEntityPublic=net.risesoft.y9public.entity
y9.feature.jpa.packagesToScanRepositoryPublic=net.risesoft.y9public.repository
yaml
y9:
feature:
file:
#是否对文件名 base64 编码
base64FileName: false
#是否用对称加密算法 AES 加密文件内容
encryptionFileContent: false
#对于不能动态扩容的存储空间 可以通过分目录挂新盘扩展存储空间
#prefix:
#私钥
#privateKey:
#公钥
#publicKey:
ftp:
#是否启用
enabled: true
host: localhost
port: 21
username: y9admin
password: '111111'
blockWhenExhausted: true
bufferSize: 10240
connectTimeOut: 50000
controlEncoding: UTF-8
dataTimeout: 1200000
fileType: 2
maxIdle: 10
maxTotal: 50
minIdle: 2
maxWaitMillis: 5400000
testOnBorrow: true
testOnCreate: true
testOnReturn: true
testWhileIdle: true
useEPSVwithIPv4: false
passiveMode: true
jpa:
#数字底座文件上传的包的需要扫描的包路径,不能更改
packagesToScanEntityPublic: net.risesoft.y9public.entity
packagesToScanRepositoryPublic: net.risesoft.y9public.repository
spring:
autoconfigure:
exclude:
- org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
- org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
#文件相关表信息需要的数据源信息,需要配置为数字底座的公共数据源
datasource:
druid:
y9-public:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/y9_public?serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&useUnicode=true&characterEncoding=utf-8&rewriteBatchedStatements=true&useCompression=true&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: 111111
initialSize: 1
maxActive: 20
maxPoolPreparedStatementPerConnectionSize: 100
maxWait: 60000
minEvictableIdleTimeMillis: 300000
minIdle: 1
poolPreparedStatements: true
testOnBorrow: false
testOnReturn: false
testWhileIdle: true
timeBetweenEvictionRunsMillis: 60000
useGlobalDataSourceStat: true
validationQuery: SELECT 1 FROM DUAL
(4)代码示例
java
package net.risesoft.controller;
import java.io.OutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import net.risesoft.y9.util.mime.ContentDispositionUtil;
import net.risesoft.y9public.entity.Y9FileStore;
import net.risesoft.y9public.service.Y9FileStoreService;
@RestController
@RequestMapping(value = "/main")
public class MainController {
Logger log = LoggerFactory.getLogger(MainController.class);
@Autowired
private Y9FileStoreService y9FileStoreService;
/**
* 根据文件唯一标示删除文件
*
* @param fileStoreId
*/
@RequestMapping(value = "/deleteFile")
public void deleteFile(@RequestParam String fileStoreId) {
try {
y9FileStoreService.deleteFile(fileStoreId);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 根据文件唯一标示下载文件
*
* @param fileStoreId
* @param response
* @param request
*/
@RequestMapping(value = "/download")
public void download(@RequestParam String fileStoreId, HttpServletResponse response, HttpServletRequest request) {
try {
Y9FileStore y9FileStore = y9FileStoreService.getById(fileStoreId);
String title = y9FileStore.getFileName();
response.setContentType("text/html;charset=UTF-8");
response.setContentType("application/octet-stream");
response.setHeader("Content-disposition", ContentDispositionUtil.standardizeAttachment(title));
OutputStream out = response.getOutputStream();
y9FileStoreService.downloadFileToOutputStream(fileStoreId, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 上传文件
*
* @param file
*/
@PostMapping(value = "/uploadFile")
public void uploadFile(MultipartFile file) {
try {
String fullPath = Y9FileStore.buildPath("aaa","bbb");
Y9FileStore y9FileStore = y9FileStoreService.uploadFile(file, fullPath, file.getOriginalFilename());
log.info("fileStoreId:{}", y9FileStore.getId());
} catch (Exception e) {
e.printStackTrace();
}
}
}
示例代码
码云地址:https://gitee.com/risesoft-y9/y9-core
该示例代码路径地址:https://gitee.com/risesoft-y9/y9-core/tree/main/y9-digitalbase-example/risenet-y9demo-file