简介
JeeSite 的文件存储,默认是存到本地服务器的磁盘里,有些情况如集群多机部署,你也可以在 application.yml 里设置 file.baseDir 文件存储路径为网络磁盘映射目录,或者集成第三方文件存储服务,具体介绍如下。
如何将文件上传到云存储?
V4.2.0 已对 MinIO、阿里云OSS、腾讯云COS、七牛云的提供支持,引入以下模块(专业版提供):
<dependency>
<groupId>com.jeesite</groupId>
<artifactId>jeesite-module-oss-client</artifactId>
<version>${project.parent.version}</version>
</dependency>
配置参数如下:
# 文件存储客户端
oss:
client:
# 配置 MinIO 服务器连接信息
# 下载地址:https://min.io/download#/windows
minio:
enabled: false
url: http://127.0.0.7:9000
accessKey: minioadmin
secretKey: minioadmin
bucketName: jeesite
# 阿里云对象存储
aliyun:
enabled: false
endpoint: http://oss-cn-zhangjiakou.aliyuncs.com
accessKeyId: O23OUY32Bmd2kfjofu34r4UI
accessKeySecret: JHdH24KJ33FHd83jJHHjiOJj8
bucketName: jeesite2
# 腾讯云对象存储
qcloud:
enabled: false
secretId: DH11KhU1R3es34w23SDf2HYM3MjbUYKBuv
secretKey: YRE2SDCv52hMLpoy47iV4BK755Vf7k
bucketName: jeesite-1833518515
region: ap-beijing
# 七牛云对象存储
qiniu:
enabled: false
domain: http://dfv35sdg.hn-bkt.clouddn.com
accessKey: cdvji45kmibj3sDFkdf5kmtKL2JRLGKJeLOrg
secretKey: gFGo5g9jr56F78fg-KJIJkmc3kIOJg45JDjfg
bucketName: jeesite2
useHttps: false
region: ~
更多的存储方式
若上述存储不能满足你的需要,你可以参考 MinIO 任意扩展其它文件存储即可。
继承 FileUploadServiceExtendSupport 类,并添加 @Service 注入到 SpringBean,举例如下:
/**
* 文件上传本地磁盘 v4.0.7+
* @author ThinkGem
* @version 2018年8月17日
*/
@Service
public class FileUploadServiceExtendImpl extends FileUploadServiceExtendSupport{
/**
* 验证文件是否真实的存在
* @param fileEntity 文件实体信息
* @return 文件存在true,不存在false
*/
public boolean fileExists(FileEntity fileEntity){
String path = fileEntity.getFileRealPath();
File localFile = new File(path);
return localFile.exists();
}
/**
* 上传文件,首次上传文件都调用(保存到文件实体表之前调用) v4.1.6
* @param fileEntity 文件实体信息
* @param fileEntity.fileRealPath 文件实际磁盘路径
* @param params.file 要上传的文件,params.* 其它相关的参数
* @return 如果上传异常或有问题,则返回错误信息数据 {result:"false", message:"文件格式错误"}
*/
public Map<String, Object> uploadFile(FileEntity fileEntity, FileUploadParams params){
// 因为此方法比较复杂,建议使用 uploadFile(FileEntity fileEntity) 方法 处理第三方存储,这个比较方便
// 若不想让文件存储到本地,直接存储到文件服务器,可以实现此方法【否则,不要重写,请删除此函数】
Map<String, Object> dataMap = MapUtils.newHashMap();
try {
// 如果是分片上传
Long chunks = params.getChunks(); // 共多少片
Long chunk = params.getChunk(); // 当前分片
Long chunkSize = params.getChunkSize(); // 分片大小
Long size = params.getSize(); // 文件大小
MultipartFile file = params.getFile(); // 上传的文件
//System.out.println("文件信息:chunks="+chunks+", chunk="+chunk
// +", chunkSize="+chunkSize+", size="+size);
if (chunks != null && chunk != null && chunkSize != null && size != null) {
// 如果总共一片(文件较小,只有一片)
if (chunks.longValue() == 1 && chunk.longValue() == 0){
//System.out.println("总共一片");
InputStream inputStream = file.getInputStream(); // 当前分片数据(文件流方式)
byte[] bytes = file.getBytes(); // 当前分片数据(字节方式方式)
// Step1:上传文件到文件服务器
}
// 上传分片数据
else{
long offset = chunk * chunkSize; // 偏移位置(当前分片的字节起始位置)
InputStream inputStream = file.getInputStream(); // 当前分片数据(文件流方式)
byte[] bytes = file.getBytes(); // 当前分片数据(字节方式方式)
// Step2:根据当前分片上传数据
// 如果全部上传完成,将临时文件转换为正式文件
if (当前已上传的文件.length() == size.longValue()){
//System.out.println("最后一片:tmpSize="+tmpFile.length()
// +", size="+size.longValue()+", "+tmpFile+" "+localFile);
// Step3:通知文件所有文件分片已经上传完成
}else{
//System.out.println("当前分片:"+String.valueOf(chunk + 1)+"/"+String.valueOf(chunks));
dataMap.put("message", Global.getText("sys.file.chunkUploading",
String.valueOf(chunk + 1), String.valueOf(chunks)));
dataMap.put("result", Global.TRUE);
return dataMap;
}
}
}else{
//System.out.println("不是分片上传");
InputStream inputStream = file.getInputStream(); // 当前分片数据(文件流方式)
byte[] bytes = file.getBytes(); // 当前分片数据(字节方式方式)
// Step4:上传文件到文件服务器
}
} catch (IOException e) {
logger.error("文件保存失败:" + fileEntity.getFileUrl(), e);
}
// 这里可以写一些代码,处理文件信息。
// 比如:文件内容类型的验证;图像压缩;图像数据存储
// 存储文件附加信息:fileEntity.setFileMetaMap(map);
return null;
}
/**
* 上传文件,首次上传文件都调用(保存到文件实体表之前调用)
* @param fileEntity 文件实体信息
* @param fileEntity.getFileRealPath() 文件实际磁盘路径
* @exception 支持抛出 throw ServiceException("文件不符合要求") v4.1.5
*/
public void uploadFile(FileEntity fileEntity){
// 当前上传的文件磁盘路径
String fileName = fileEntity.getFileRealPath();
try {
// 这里写上传到文件服务器的代码
} catch (Exception e) {
throw ExceptionUtils.unchecked(e);
} finally {
// 文件上传后删除临时文件
FileUtils.deleteFile(fileName);
}
}
/**
* 保存上传文件信息,每次上传都调用(保存文件和用户关系数据之前调用)
* @param fileUpload 文件上传信息,包括文件实体
* @exception 支持抛出 throw ServiceException("文件不符合要求") v4.1.5
*/
public void saveUploadFile(FileUpload fileUpload){
// 如果想上传后,即保存业务关联的信息,可以打开如下注释
//FileEntity fileEntity = fileUpload.getFileEntity();
//FileUploadParams params = fileEntity.getFileUploadParams();
//fileUpload.setBizKey(params.getBizKey());
//fileUpload.setBizType(params.getBizType());
}
/**
* 获取访问文件的URL地址
* @param fileUpload 文件上传的信息,包括文件实体
* @return 无文件下载地址,则返回null,方便后续处理
*/
public String getFileUrl(FileUpload fileUpload){
return fileUpload.getFileEntity().getFileUrl();
}
/**
* 下载文件到浏览器
* @param fileUpload 文件上传的信息
* @param request 请求对象,可能断点续传用
* @param response 响应对象,输出文件流使用
* @return 如果不是文件流数据,也可返回文件的URL地址进行跳转,如果文件不存在返回404字符串
*/
public String downFile(FileUpload fileUpload, HttpServletRequest request, HttpServletResponse response){
FileEntity fileEntity = fileUpload.getFileEntity();
File file = new File(fileEntity.getFileRealPath());
if (file.exists()){
FileUtils.downFile(file, request, response, fileUpload.getFileName());
return null;
}
return "404";
}
}