环境
springboot2.1.15
阿里oos服务器
fastdfs服务器
文件服务应用
小文件 如图片上传到fastdfs上,大文件如视频上传到阿里云oos服务器上
分布式文件代理服务器实现
实现分析
1、FileUpload抽象接口定义了上传方法,分别给他写了两种实现
2、AliyunOOSFileUpload主要上传视频文件
3、FastDfsFileUpload主要上传图片文件
4、FileUploadProxy是 代理对象,主要供用户访问,调用了FileUpload的upload方法,为客户提供不同文件上传调用
5、FileController是控制器,用于接收客户提交的文件,并调用代理FileUploadProxy实现文件上传
代码实现
application.yml
aliyun:
oss:
endpoint: #####
accessKey: #####
accessKeySecret: #####
bucketName: #####
key: video/
backurl: #访问地址配置
fastdfs:
url: http://192.168.211.137:28181/
fileupload:
filemap:
aliyunOSSFileUpload: mp4,avi
fastdfsFileUpoad: jpg,png,peg
FileUpload
public interface FileUpload {
String upload(byte[] buffers,String extname);
}
AliyunOSSFileUpload
@Component(value = "aliyunOSSFileUpload")
public class AliyunOOSFileUpload implements FileUpload {
@Value("${aliyun.oss.endpoint}")
private String endpoint;
@Value("${aliyun.oss.accessKey}")
private String accessKey;
@Value("${aliyun.oss.accessKeySecret}")
private String accessKeySecret;
@Value("${aliyun.oss.key}")
private String key;
@Value("${aliyun.oss.bucketName}")
private String bucketName;
@Value("${aliyun.oss.backurl}")
private String backurl;
@Override
public String upload(byte[] buffers, String extname) {
String realName = UUID.randomUUID().toString()+"."+extname;
OSS oosClient = new OSSClientBuilder().build(endpoint, accessKey, accessKeySecret);
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key + realName, new ByteArrayInputStream(buffers));
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentType(FileUtil.getContentType("."+extname));
putObjectRequest.setMetadata(objectMetadata);
oosClient.putObject(putObjectRequest);
oosClient.shutdown();
return backurl+realName;
}
}
FastdfsFileUpoad
@Component(value = "fastdfsFileUpoad")
public class FastdfsFileUpoad implements FileUpload {
@Value("${fastdfs.url}")
private String url;
/***
* 文件上传
* @param buffers:文件字节数组
* @param extName:后缀名
* @return
*/
@Override
public String upload(byte[] buffers, String extName) {
/***
* 文件上传后的返回值
* uploadResults[0]:文件上传所存储的组名,例如:group1
* uploadResults[1]:文件存储路径,例如:M00/00/00/wKjThF0DBzaAP23MAAXz2mMp9oM26.jpeg
*/
String[] uploadResults = null;
try {
//获取StorageClient对象
StorageClient storageClient = getStorageClient();
//执行文件上传
uploadResults = storageClient.upload_file(buffers, extName, null);
return url+uploadResults[0]+"/"+uploadResults[1];
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/***
* 初始化tracker信息
*/
static {
try {
//获取tracker的配置文件fdfs_client.conf的位置
String filePath = new ClassPathResource("fdfs_client.conf").getPath();
//加载tracker配置信息
ClientGlobal.init(filePath);
} catch (Exception e) {
e.printStackTrace();
}
}
/***
* 获取StorageClient
* @return
* @throws Exception
*/
public static StorageClient getStorageClient() throws Exception{
//创建TrackerClient对象
TrackerClient trackerClient = new TrackerClient();
//通过TrackerClient获取TrackerServer对象
TrackerServer trackerServer = trackerClient.getConnection();
//通过TrackerServer创建StorageClient
StorageClient storageClient = new StorageClient(trackerServer,null);
return storageClient;
}
}
FileUploadProxy
@Component
@ConfigurationProperties(prefix = "fileupload")
public class FileUploadProxy implements ApplicationContextAware {
private Map<String, List<String>> filemap;
private ApplicationContext applicationContext;
public String upload(MultipartFile file) throws IOException {
FileUpload fileUpload = null;
String extension = StringUtils.getFilenameExtension(file.getOriginalFilename());
byte[] bytes = file.getBytes();
aa:
for (Map.Entry<String, List<String>> entry : filemap.entrySet()) {
List<String> values = entry.getValue();
for (String value : values) {
if (value.equals(extension)) {
System.out.println(extension);
fileUpload = applicationContext.getBean(entry.getKey(),FileUpload.class);
break aa;
}
}
}
if (fileUpload == null) {
fileUpload = applicationContext.getBean("fastdfsFileUpoad",FileUpload.class);
}
return fileUpload.upload(bytes,extension);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public void setFilemap(Map<String, List<String>> filemap) {
this.filemap = filemap;
}
}
FileController
@RestController
@RequestMapping(value = "/file")
public class FileController {
@Autowired
private FileUploadProxy fileUploadProxy;
/***
* 文件上传
* @param file
* @return
* @throws IOException
*/
@PostMapping(value = "/upload")
public String upload(MultipartFile file) throws IOException {
// return fileUploadProxy.upload(file.getBytes(), StringUtils.getFilenameExtension(file.getOriginalFilename()));
return fileUploadProxy.upload(file);
}
}