pom引入依赖包
<!--阿里云oss-->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.8.0</version>
</dependency>
阿里云OSS配置(yml)
#阿里云oss
aliyun:
endpoint: http://oss-cn-beijing.aliyuncs.com # oss对外服务的访问域名
access-key-id: *****njArc******3s # 访问身份验证中用到用户标识
access-key-secret: *******WB9**** # 用户用于加密签名字符串和oss用来验证签名字符串的密钥
bucket: *** #桶名(文件目录)
dir:
工具类,复制即用
/**
* 阿里云-OSS文件类
*/
@Slf4j
@Configuration
@PropertySource("classpath:/application.yml")
@Component
public class AliOssCloudUtil {
@Value("${aliyun.endpoint:#{null}}")
private String endpoint;
@Value("${aliyun.access-key-id:#{null}}")
private String accessKeyId;
@Value("${aliyun.access-key-secret:#{null}}")
private String accessKeySecret;
@Value("${aliyun.bucket:#{null}}")
private String bucketName;
@Value("${aliyun.dir:#{null}}")
private String dir;
public String getDir() {
return dir;
}
/**
* 获取OSS
* @return
*/
public OSS getOSSClient(){
return new OSSClientBuilder().build(endpoint,accessKeyId,accessKeySecret);
}
/**
* 上传到OSS服务器
*
* @param instream 文件流
* @param fileName 文件名称 包括后缀名
* @return 出错返回"" ,唯一MD5数字签名
*/
public String uploadFile2OSS(InputStream instream, String fileName) {
OSS ossClient = getOSSClient();
String ret = "";
// 判断bucket是否已经存在,不存在进行创建
if (!doesBucketExist(ossClient)) {
createBucket(ossClient);
}
try {
//创建上传Object的Metadata
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentLength(instream.available());
objectMetadata.setCacheControl("no-cache");
objectMetadata.setHeader("Pragma", "no-cache");
objectMetadata.setContentType(getcontentType(fileName.substring(fileName.lastIndexOf("."))));
objectMetadata.setContentDisposition("inline;filename=" + fileName);
// 指定上传文件操作时是否覆盖同名Object。
// 不指定x-oss-forbid-overwrite时,默认覆盖同名Object。
// 指定x-oss-forbid-overwrite为false时,表示允许覆盖同名Object。
// 指定x-oss-forbid-overwrite为true时,表示禁止覆盖同名Object,如果同名Object已存在,程序将报错。
objectMetadata.setHeader("x-oss-forbid-overwrite", "false");
String objectName = dir + fileName;
//上传文件
ossClient.putObject(bucketName, objectName, instream, objectMetadata);
// 设置URL过期时间(7天)
Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000 * 24 * 7);
URL url = ossClient.generatePresignedUrl(bucketName, objectName,expiration);
log.info(objectName);
ret = url.toString().split("\\?")[0];
} catch (IOException e) {
e.printStackTrace();
} finally {
ossClient.shutdown();
try {
if (instream != null) {
instream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return ret;
}
/**
* 获取文件在线地址
* @param objectName 文件路径 filePath
* @param expiration 过期时间
* @return 返回文件在线路径
*/
public String getOnlineAddress(String objectName,Date expiration){
OSS ossClient = getOSSClient();
String ret = null;
try {
URL url = ossClient.generatePresignedUrl(bucketName, objectName,expiration);
ret = url.toString().split("\\?")[0];
} catch (ClientException e) {
e.printStackTrace();
}finally {
ossClient.shutdown();
}
return ret;
}
/**
* 判断文件是否存在。doesObjectExist还有一个参数isOnlyInOSS,
* 如果为true则忽略302重定向或镜像;如果为false,则考虑302重定向或镜像。
* yourObjectName 表示上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。
*
* @return 存在返回true
*/
public boolean doesObjectExist(OSS ossClient,String objectName) {
boolean exists = ossClient.doesObjectExist(bucketName, dir + objectName);
return exists;
}
/**
* 判断Bucket是否存在
*
* @return 存在返回true
*/
public boolean doesBucketExist(OSS ossClient) {
boolean exists = ossClient.doesBucketExist(bucketName);
return exists;
}
/**
* 创建Bucket
*/
public void createBucket(OSS ossClient) {
CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
// 设置bucket权限为公共读,默认是私有读写
createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
// 设置bucket存储类型为低频访问类型,默认是标准类型
createBucketRequest.setStorageClass(StorageClass.IA);
boolean exists = ossClient.doesBucketExist(bucketName);
if (!exists) {
try {
ossClient.createBucket(createBucketRequest);
// 关闭client
// ossClient.shutdown();
} catch (Exception e) {
log.error(e.getMessage());
}
}
}
/**
* 判断OSS服务文件上传时文件的contentType
* @param FilenameExtension 文件后缀
* @return String
*/
public static String getcontentType(String FilenameExtension) {
if ("bmp".equalsIgnoreCase(FilenameExtension)) {
return "image/bmp";
}
if ("gif".equalsIgnoreCase(FilenameExtension)) {
return "image/gif";
}
if ("jpeg".equalsIgnoreCase(FilenameExtension) ||
"jpg".equalsIgnoreCase(FilenameExtension) ||
"png".equalsIgnoreCase(FilenameExtension)) {
return "image/jpeg";
}
if ("html".equalsIgnoreCase(FilenameExtension)) {
return "text/html";
}
if ("txt".equalsIgnoreCase(FilenameExtension)) {
return "text/plain";
}
if ("vsd".equalsIgnoreCase(FilenameExtension)) {
return "application/vnd.visio";
}
if ("pptx".equalsIgnoreCase(FilenameExtension) ||
"ppt".equalsIgnoreCase(FilenameExtension)) {
return "application/vnd.ms-powerpoint";
}
if ("docx".equalsIgnoreCase(FilenameExtension) ||
"doc".equalsIgnoreCase(FilenameExtension)) {
return "application/msword";
}
if ("xml".equalsIgnoreCase(FilenameExtension)) {
return "text/xml";
}
return "image/jpeg";
}
/**
* 通过文件名下载文件
*
* @param objectName 要下载的文件名
* @param localFileName 本地要创建的文件名
*/
public void downloadFile(HttpServletResponse response, String objectName, String localFileName){
// 创建OSSClient实例。
OSS ossClient = getOSSClient();
try {
// ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流。
OSSObject ossObject = ossClient.getObject(bucketName, objectName);
// 读去Object内容 返回
BufferedInputStream in = new BufferedInputStream(ossObject.getObjectContent());
BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
//通知浏览器以附件形式下载
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(objectName, "utf-8"));
//BufferedOutputStream out=new BufferedOutputStream(new FileOutputStream(new File("f:\\a.txt")));
byte[] car = new byte[1024];
int L = 0;
while ((L = in.read(car)) != -1) {
out.write(car, 0, L);
}
if (out != null) {
out.flush();
out.close();
}
if (in != null) {
in.close();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭OSSClient。
ossClient.shutdown();
}
}
/**
* 批量下载为zip
* @param response
* @param fileName oss文件路径集合
* @param fileName 下载出来的zip文件名(一般以合同名命名) 如:测试合同,zip
*/
public void downForZip( HttpServletResponse response,List<String> filePath,String fileName){
// 创建临时文件
File zipFile = null;
try {
zipFile = File.createTempFile("test", ".zip");
FileOutputStream f = new FileOutputStream(zipFile);
/**
* 作用是为任何OutputStream产生校验和
* 第一个参数是制定产生校验和的输出流,第二个参数是指定Checksum的类型 (Adler32(较快)和CRC32两种)
*/
CheckedOutputStream csum = new CheckedOutputStream(f, new Adler32());
// 用于将数据压缩成Zip文件格式
ZipOutputStream zos = new ZipOutputStream(csum);
OSS ossClient= getOSSClient();
for (String ossFile : filePath) {
// 获取Object,返回结果为OSSObject对象
OSSObject ossObject = ossClient.getObject(bucketName, ossFile);
// 读去Object内容 返回
InputStream inputStream = ossObject.getObjectContent();
// 对于每一个要被存放到压缩包的文件,都必须调用ZipOutputStream对象的putNextEntry()方法,确保压缩包里面文件不同名
String name=ossFile.substring(ossFile.lastIndexOf("/")+1);
zos.putNextEntry(new ZipEntry(name));
int bytesRead = 0;
// 向压缩文件中输出数据
while ((bytesRead = inputStream.read()) != -1) {
zos.write(bytesRead);
}
inputStream.close();
zos.closeEntry(); // 当前文件写完,定位为写入下一条项目
}
zos.close();
response.reset();
response.setContentType("text/plain");
response.setContentType("application/octet-stream; charset=utf-8");
response.setHeader("Location", fileName);
response.setHeader("Cache-Control", "max-age=0");
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
FileInputStream fis = new FileInputStream(zipFile);
BufferedInputStream buff = new BufferedInputStream(fis);
BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
byte[] car = new byte[1024];
int l = 0;
while (l < zipFile.length()) {
int j = buff.read(car, 0, 1024);
l += j;
out.write(car, 0, j);
}
// 关闭流
fis.close();
buff.close();
out.close();
ossClient.shutdown();
// 删除临时文件
zipFile.delete();
} catch (IOException e1) {
e1.printStackTrace();
}catch (Exception e) {
e.printStackTrace();
}
}
}