最近项目中需要通过OSS来实现文件的上传和下载,特此记录,以便日后查阅。
首先你需要开通阿里云的OSS服务,注册得到相关的配置信息:endPoint、accessKeyId、accessKeySecret、bucketName。
1、引入依赖
com.aliyun.oss
aliyun-sdk-oss
2.4.0
commons-fileupload
commons-fileupload
1.3.1
2、properties配置
# 文件客户端类型
file.client.type=oss
# OSS
file.oss.endPoint=http://oss-cn-hangzhou.aliyuncs.com
file.oss.accessKeyId=去OSS控制台获取
file.oss.accessKeySecret=去OSS控制台获取
file.oss.bucketName=这个自己创建bucket时的命名
file.oss.rootDir=data
3、引导类配置
/**
* 引导类
*
* @author zhangzhixiang
* @date 2018/09/18 14:51:39
*/
@Configuration
public class BootstrapConsts {
@Value("${file.client.type}")
private String fileClientType;
@Value("${file.oss.endPoint}")
private String endPoint;
@Value("${file.oss.accessKeyId}")
private String accessKeyId;
@Value("${file.oss.accessKeySecret}")
private String accessKeySecret;
@Value("${file.oss.bucketName}")
private String bucketName;
@Value("${file.oss.rootDir}")
private String rootDir;
/**
* 文件客户端类型
*/
public static String file_client_type;
/**
* OSS地址(不同服务器,地址不同)
*/
public static String end_point;
/**
* OSS键id(去OSS控制台获取)
*/
public static String access_key_id;
/**
* OSS秘钥(去OSS控制台获取)
*/
public static String access_key_secret;
/**
* OSS桶名称(这个是自己创建bucket时候的命名)
*/
public static String bucket_name;
/**
* OSS根目录
*/
public static String root_dir;
@PostConstruct
private void initial() {
file_client_type = fileClientType;
end_point = endPoint;
access_key_id = accessKeyId;
access_key_secret = accessKeySecret;
bucket_name = bucketName;
root_dir = rootDir;
}
}
4、文件工厂类
/**
* 文件操作客户端生成类
*
* @author zhangzhixiang
* @data 2018/09/14 11:56:43
*/
public class ClientFactory {
private static final Logger logger = LoggerFactory.getLogger(ClientFactory.class);
/**
* 根据类型获取文件操作客户端
*
* @param type
* @return
*/
public static FileClient createClientByType(String type) {
FileClient client = null;
switch (type) {
case "local":
client = LocalClient.create();
break;
case "oss":
client = OssClient.create();
break;
default:
client = null;
logger.info("the type of fileClient does not exist.please check the type.type={}", type);
break;
}
return client;
}
}
5、文件接口
/**
* 本地文件操作类
*
* @author zhangzhixiang
* @data 2018/09/14 11:56:43
*/
public interface FileClient {
/**
* 获取文件流
*
* @author zhangzhixiang
* @date 2018/10/17 10:59:43
* @param code
* @return java.io.InputStream
*/
InputStream getFileStream(String code);
/**
* 上传文件
*
* @param inputStream
* @param filePath
* @param ext
* @author zhangzhixiang
* @date 2018/10/17 10:59:43
* @return boolean
*/
String upload(InputStream inputStream, String filePath, String ext) throws Exception;
/**
* 下载文件
*
* @param response
* @param filePath
* @param name
* @author zhangzhixiang
* @date 2018/10/17 10:59:43
* @return void
*/
void download(HttpServletResponse response, String filePath, String name) throws Exception;
/**
* 删除文件
*
* @param dirPath
* @author zhangzhixiang
* @date 2018/10/17 10:59:43
* @return void
*/
void delete(String dirPath);
/**
* 获得url地址
*
* @param key
* @author zhangzhixiang
* @date 2018/10/17 10:59:43
* @return java.lang.String
*/
String getUrl(String key);
}
6、常量类定义
/**
* @Description:简单常亮定义
* @Author:zhangzhixiang
* @CreateDate:2018/08/31 11:34:56
* @Version:1.0
*/
public class SimpleConsts {
public static final Integer INPUT_BUFFER_SIZE = 8192;
}
7、OSS客户端配置
/**
* @Description:OSS客户端配置
* @Author:zhangzhixiang
* @CreateDate:2018/08/31 11:34:56
* @Version:1.0
*/
public class OssClient implements FileClient {
private static final Logger logger = LoggerFactory.getLogger(OssClient.class);
private final char PATH_SEPARATOR = System.getProperty("file.separator").toCharArray()[0];
private static OssClient ossClient;
/**
* @Description:获取aliOSS对象
* @Author:zhangzhixiang
*/
private OSSClient getClient() {
OSSClient ossClient = null;
try {
ossClient = new OSSClient(BootstrapConsts.end_point, BootstrapConsts.access_key_id, BootstrapConsts.access_key_secret);
} catch(Exception e){
logger.error("**********************OSSClient bean create error.**********************",e);
ossClient = null;
}
return ossClient;
}
/**
* @Description:创建OssClient
* @Author:zhangzhixiang
*/
public static FileClient create() {
if(null == ossClient) {
synchronized (logger) {
if(null == ossClient) {
ossClient = new OssClient();
}
}
}
return ossClient;
}
/**
* @Description:根据code获取文件流
* @Author:zhangzhixiang
*/
@Override
public InputStream getFileStream(String code) {
OSSClient aliOssClient = getClient();
OSSObject ossObject = aliOssClient.getObject(BootstrapConsts.bucket_name, BootstrapConsts.root_dir + PATH_SEPARATOR + code);
return ossObject.getObjectContent();
}
/**
* @Description:上传文件
* @Author:zhangzhixiang
*/
@Override
public String upload(InputStream inputStream, String code, String ext) {
OSSClient aliOssClient = getClient();
code = UUIDUtils.getUUID();
PutObjectResult putResult = aliOssClient.putObject(BootstrapConsts.bucket_name, BootstrapConsts.root_dir + PATH_SEPARATOR + code + ext, inputStream);
aliOssClient.shutdown();
return StringUtils.isNotEmpty(putResult.getETag()) ? BootstrapConstss.root_dir + PATH_SEPARATOR + code + ext : null;
}
/**
* @Description:下载文件
* @Author:zhangzhixiang
*/
@Override
public void download(HttpServletResponse response, String code, String name) {
OSSClient aliOssClient = getClient();
OSSObject ossObject = aliOssClient.getObject(BootstrapConsts.bucket_name, BootstrapConsts.root_dir + PATH_SEPARATOR + code);
try (InputStream fis = ossObject.getObjectContent(); OutputStream fos = response.getOutputStream(); BufferedOutputStream bos = new BufferedOutputStream(fos)) {
response.setContentType("application/octet-stream; charset=UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + new String(name.getBytes("UTF-8"), "ISO-8859-1"));
int bytesRead = 0;
byte[] buffer = new byte[SimpleConsts.INPUT_BUFFER_SIZE];
while((bytesRead = fis.read(buffer, 0, SimpleConsts.INPUT_BUFFER_SIZE)) != -1) {
bos.write(buffer, 0, bytesRead);
}
bos.flush();
} catch (Exception e){
logger.error("**********************OssClient-->download throw Exception.name:{},code:{}**********************", name, code, e);
}
aliOssClient.shutdown();
}
/**
* @Description:删除文件
* @Author:zhangzhixiang
*/
@Override
public void delete(String code) {
OSSClient aliOssClient = getClient();
boolean flag = aliOssClient.doesObjectExist(BootstrapConsts.bucket_name, code);
if(false == flag) {
logger.info("**********************The object represented by key:{} does not exist in bucket:{}.**********************", code, BootstrapConsts.bucket_name);
}
aliOssClient.deleteObject(BootstrapConsts.bucket_name, code);
}
/**
* @Description:获取文件地址
* @Author:zhangzhixiang
*/
@Override
public String getUrl(String code) {
OSSClient aliOssClient = getClient();
//设置URL过期时间为10年
Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 10);
//生成URL
URL url = aliOssClient.generatePresignedUrl(BootstrapConsts.bucket_name, code, expiration);
if(url != null) {
return url.toString();
}
return null;
}
/**
* @Description:生成文件名
* @Author:zhangzhixiang
*/
private String createFileName(String ext) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
return simpleDateFormat .format(new Date()) + (int)(Math.random() * 900 + 100) + ext;
}
/**
* @Description:生成OSS文件唯一标识
* @Author:zhangzhixiang
*/
private String generateKey(String filename) {
StringBuffer buffer = new StringBuffer();
try {
buffer.append(filename);
buffer.append(Math.random());
return EncodeUtil.encodeFromMD5ToBase64(buffer.toString());
} catch(NoSuchAlgorithmException e) {
e.printStackTrace();
} catch(UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
}
8、UUIDUtils类
/**
* @author zxzhang on 2020/8/1
*/
public class UUIDUtils {
/**
* 32位默认长度的uuid
*
* @param
* @return java.lang.String
* @author zxzhang
* @date 2020/8/1
*/
public static String getUUID() {
return UUID.randomUUID().toString().replace("-", "");
}
/**
* 获取指定长度uuid
*
* @param len
* @return java.lang.String
* @author zxzhang
* @date 2020/8/1
*/
public static String getUUID(int len) {
if (0 >= len) {
return null;
}
String uuid = getUUID();
System.out.println(uuid);
StringBuffer str = new StringBuffer();
for (int i = 0; i < len; i++) {
str.append(uuid.charAt(i));
}
return str.toString();
}
}
9、本地客户端配置
/**
* @Description:本地客户端配置
* @Author:zhangzhixiang
* @CreateDate:2018/10/18 11:47:36
* @Version:1.0
*/
public class LocalClient implements FileClient {
private static final Logger logger = LoggerFactory.getLogger(LocalClient.class);
private final char PATH_SEPARATOR = System.getProperty("file.separator").toCharArray()[0];
private static LocalClient client;
private LocalClient() {}
/**
* @Description:创建客户端
* @Author:zhangzhixiang
*/
public static FileClient create() {
if(null == client) {
synchronized (logger) {
if(null == client) {
if(null == client) {
client = new LocalClient();
}
}
}
}
return client;
}
/**
* @Description:获得文件流
* @Author:zhangzhixiang
*/
@Override
public InputStream getFileStream(String code) {
return null;
}
/**
* @Description:上传文件
* @Author:zhangzhixiang
*/
@Override
public String upload(InputStream inputStream, String filePath, String ext) throws Exception {
File dir = new File(filePath);
FileOutputStream out = null;
try {
if(!dir.exists()) {
dir.mkdirs();
}
filePath = filePath + PATH_SEPARATOR + createFileName(ext);
File file = new File(filePath);
out = new FileOutputStream(file);
int b = 0;
byte[] buffer = new byte[512];
while ((b = inputStream.read(buffer)) != -1) {
out.write(buffer, 0, b);
}
out.flush();
return filePath;
} catch (IOException e) {
logger.info("**************************LocalClient-->upload throw Exception.filePath:{}**************************", filePath);
throw e;
} finally {
if(out != null) {
out.close();
}
if(inputStream != null) {
inputStream.close();
}
}
}
/**
* @Description:下载文件
* @Author:zhangzhixiang
*/
@Override
public void download(HttpServletResponse response, String filePath, String name) throws Exception {
response.setContentType("application/octet-stream; charset=UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + new String(name.getBytes("UTF-8"), "ISO-8859-1"));
File file = new File(filePath + PATH_SEPARATOR + name);
try (InputStream fis = new FileInputStream(file); BufferedInputStream bis = new BufferedInputStream(fis); OutputStream fos = response.getOutputStream(); BufferedOutputStream bos = new BufferedOutputStream(fos)) {
int bytesRead = 0;
byte[] buffer = new byte[SimpleConsts.INPUT_BUFFER_SIZE];
while ((bytesRead = bis.read(buffer, 0, SimpleConsts.INPUT_BUFFER_SIZE)) != -1) {
bos.write(buffer, 0, bytesRead);
}
bos.flush();
} catch(Exception e) {
logger.info("**************************LocalClient-->download throw Exception.filePath:{}**************************", filePath);
}
}
/**
* @Description:删除文件
* @Author:zhangzhixiang
*/
@Override
public void delete(String dirPath) {
File dir = new File(dirPath);
if (dir.exists()) {
if(dir.isFile()) {
dir.delete();
} else {
File[] tmp = dir.listFiles();
for(int i = 0; i < tmp.length; i++) {
if (tmp[i].isDirectory()) {
delete(dirPath + PATH_SEPARATOR + tmp[i].getName());
} else {
tmp[i].delete();
}
}
dir.delete();
}
}
}
/**
* @Description:获取文件地址
* @Author:zhangzhixiang
*/
@Override
public String getUrl(String key) {
return null;
}
/**
* @Description:生成文件名
* @Author:zhangzhixiang
*/
private String createFileName(String ext) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
return simpleDateFormat.format(new Date()) + (int) (Math.random() * 900 + 100) + ext;
}
}
10、controller层
/**
* @Description:文件接口-controller
* @Author:zhangzhixiang
* @CreateDate:2018/10/18 11:47:36
* @Version:1.0
*/
@RestController
@RequestMapping("/api/ops/file")
public class FileController extends ExceptionHandlerAdvice {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* @Description:文件上传
* @Author:zhangzhixiang
*/
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public ResponseResult upload(@RequestParam("file") MultipartFile file) throws Exception {
Map map = new HashMap<>(64);
FileClient fileClient = ClientFactory.createClientByType(BootstrapConsts.file_client_type);
String ext = this.getExtName(file.getOriginalFilename());
String code = fileClient.upload(file.getInputStream(), "/", ext);
String url = fileClient.getUrl(code);
map.put("code", code.substring(code.lastIndexOf("/") + 1).substring(code.lastIndexOf("\\") + 1));
map.put("url", url);
return new ResponseResult().setSuccess(true).setData().setCode(ResultCode.SUCCESS.getCode());
}
/**
* @Description:文件下载
* @Author:zhangzhixiang
*/
@RequestMapping(value = "/download", method = RequestMethod.GET)
public ResponseResult download(@RequestParam("code") String code, @RequestParam("name") String name, HttpServletResponse response) throws Exception {
FileClient fileClient = ClientFactory.createClientByType(BootstrapConsts.file_client_type);
fileClient.download(response, code, name);
return new ResponseResult().setSuccess(true).setMessage(ResultCode.SUCCESS.getMessage()).setCode(ResultCode.SUCCESS.getCode());
}
/**
* 获取文件扩展名
* @return
*/
public static String getExtName(String filename) {
int index = filename.lastIndexOf(".");
if (index == -1) {
return null;
}
String result = filename.substring(index);
return result;
}
}
全篇文章完全纯手打,如果觉得对您有帮助,记得加关注给好评哟~~