package com.ruoyi.common.utils.qiniu;
import com.alibaba.fastjson2.JSONObject;
import com.google.gson.Gson;
import com.qiniu.cdn.CdnManager;
import com.qiniu.cdn.CdnResult;
import com.qiniu.common.Zone;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.storage.model.FileInfo;
import com.qiniu.storage.persistent.FileRecorder;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.common.utils.uuid.UUIDUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.Mac;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class QiniuUtils {
public static Logger logger = LoggerFactory.getLogger(QiniuUtils.class);
/**
* 描述:上传图片 (普通上传)
* 禁止直接使用 请通过CommonUtils.uploadFileBefore()使用
* @param file
* @return
*/
public static String uploadFile(MultipartFile file, JSONObject jsonObject){
try {
String ACCESS_KEY = jsonObject.getString("ACCESS_KEY");
String SECRET_KEY = jsonObject.getString("SECRET_KEY");
String BUCKET = jsonObject.getString("BUCKET");//桶名称
String DOMAIN_URL = jsonObject.getString("DOMAIN_URL");//域名 例:http://www.baidu.com/
String ZIP_PATH = jsonObject.getString("ZIP_PATH");//上传文件到七牛云指定路径
//处理文件
if(file.isEmpty()){
return "";
}
//构造一个带指定Zone对象的配置类
Configuration cfg = new Configuration(Zone.zone1());
UploadManager uploadManager = new UploadManager(cfg);
//默认不指定key的情况下,以文件内容的hash值作为文件名
String key = ZIP_PATH + file.getOriginalFilename();//genKey(file.getOriginalFilename());
logger.info("图片:" + key);
//授权Token
Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
String upToken = auth.uploadToken(BUCKET);
Response response = uploadManager.put(file.getInputStream(),key,upToken,null, null);
//解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
System.out.println(putRet.key);
System.out.println(putRet.hash);
return DOMAIN_URL+key;
} catch (RuntimeException ex) {
ex.printStackTrace();
throw new RuntimeException(ex.getMessage());
} catch (Exception ex2) {
ex2.printStackTrace();
}finally{
try {
if(file.getInputStream() != null){
file.getInputStream().close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return "";
}
/**
* 描述:上传图片(普通上传)
* 禁止直接使用 请通过CommonUtils.uploadFileBefore()使用
* @param file
* @return
*/
public static String uploadFile(File file,JSONObject jsonObject){
try {
String ACCESS_KEY = jsonObject.getString("ACCESS_KEY");
String SECRET_KEY = jsonObject.getString("SECRET_KEY");
String BUCKET = jsonObject.getString("BUCKET");//桶名称
String DOMAIN_URL = jsonObject.getString("DOMAIN_URL");//域名 例:http://www.baidu.com/
String ZIP_PATH = jsonObject.getString("ZIP_PATH");//上传文件到七牛云指定路径
//处理文件
if(StringUtils.isEmpty(file.getPath())){
return "";
}
//构造一个带指定Zone对象的配置类
Configuration cfg = new Configuration(Zone.zone1());
UploadManager uploadManager = new UploadManager(cfg);
//默认不指定key的情况下,以文件内容的hash值作为文件名
String key = ZIP_PATH + file.getName();//genKey(file.getName());
logger.info("图片:" + key);
//授权Token
Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
String upToken = auth.uploadToken(BUCKET);
Response response = uploadManager.put(file,key,upToken);
//解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
System.out.println(putRet.key);
System.out.println(putRet.hash);
return DOMAIN_URL+key;
} catch (RuntimeException ex) {
ex.printStackTrace();
throw new RuntimeException(ex.getMessage());
} catch (Exception ex2) {
ex2.printStackTrace();
}
return "";
}
/**
* 描述:删除图片
* @param key
*/
public static double delFile(String key,JSONObject jsonObject){
double fileSize = 0;
String ACCESS_KEY = jsonObject.getString("ACCESS_KEY");
String SECRET_KEY = jsonObject.getString("SECRET_KEY");
String BUCKET = jsonObject.getString("BUCKET");
String DOMAIN_URL = jsonObject.getString("DOMAIN_URL");
key = key.replace(DOMAIN_URL,"");
//FileInfo fileInfo = getFileMags(key, jsonObject);
//fileSize = (double)fileInfo.fsize/1048576;
//构造一个带指定Zone对象的配置类
Configuration cfg = new Configuration(Zone.zone1());
Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
BucketManager bucketManager = new BucketManager(auth, cfg);
try {
bucketManager.delete(BUCKET, key);
} catch (QiniuException ex) {
//如果遇到异常,说明删除失败
System.err.println(ex.code());
System.err.println(ex.response.toString());
}
return fileSize;
}
//获取图片存储空间
public static double getFileSize(String keys, JSONObject jsonObject){
if(StringUtils.isBlank(keys)){
return 0;
}
String[] keyList = keys.split(",");
double fileSize = 0;
if(keyList != null && keyList.length > 0){
for(String key:keyList){
String[] nn = key.split("/");
key = "image/" + nn[nn.length-1];
FileInfo fileInfo = getFileMags(key, jsonObject);
if(fileInfo != null && fileInfo.fsize > 0){
fileSize += (double)fileInfo.fsize/1048576;
}
}
}
return fileSize;
}
/**
* 下载对象文件
* @param fileUrl
* @param jsonObject
* @param response
*/
public static void downFile(String fileUrl, JSONObject jsonObject, HttpServletResponse response){
String ACCESS_KEY = jsonObject.getString("ACCESS_KEY");
String SECRET_KEY = jsonObject.getString("SECRET_KEY");
String DOMAIN_URL = jsonObject.getString("DOMAIN_URL");
int bytesum = 0;
int byteread = 0;
InputStream input = null;
try{
String end = fileUrl.substring(fileUrl.lastIndexOf("/")+1);
String start = fileUrl.substring(0, fileUrl.lastIndexOf("/"));
String domainOfBucket = DOMAIN_URL+start;
String encodedFileName = URLEncoder.encode(end, "utf-8").replace("+", "%20");
String publicUrl = String.format("%s/%s", domainOfBucket, encodedFileName);
Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
long expireInSeconds = 3600;//1小时,可以自定义链接过期时间
String finalUrl = auth.privateDownloadUrl(publicUrl, expireInSeconds);
String[] nn = fileUrl.split("/");
String[] split = nn[nn.length-1].split("\\.");
// path是指欲下载的文件的路径。
URL url = new URL(finalUrl);
URLConnection conn = url.openConnection();
input = conn.getInputStream();
response.reset();
response.setContentType("text/html;charset=ISO8859-1");
response.setContentType("bin");
response.addHeader("Content-Disposition", "attachment; filename=\"" + new String(UUIDUtil.get16UUID().toString().getBytes("ISO8859-1"), "ISO8859-1") + "." + split[split.length-1] + "\"");
byte[] buffer = new byte[1204];
while ((byteread = input.read(buffer)) != -1) {
bytesum += byteread;
response.getOutputStream().write(buffer, 0, byteread);
}
}catch(Exception e){
e.printStackTrace();
}finally{
try {
if(input!=null){
input.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
*
* @param key 图片路径
* @param jsonObject
*/
public static void refreshUrls(String key,JSONObject jsonObject){
String accessKey = jsonObject.getString("ACCESS_KEY");
String secretKey = jsonObject.getString("SECRET_KEY");
Auth auth = Auth.create(accessKey, secretKey);
CdnManager c = new CdnManager(auth);
//待刷新的链接列表
String[] urls = new String[]{
key
//....
};
try {
//单次方法调用刷新的链接不可以超过100个
CdnResult.RefreshResult result = c.refreshUrls(urls);
System.out.println(result.code);
//获取其他的回复内容
} catch (QiniuException e) {
System.err.println(e.response.toString());
}
}
/**
* 描述:批量删除文件
* @param ids
*/
/*public static double batchDelFile(String ids){
if(StringUtils.isBlank(ids)){
return 0;
}
double fileSize = 0;
//单次批量请求的文件数量不得超过1000
String[] keyList = ids.split(",");
List<String> keys = new ArrayList<String>();
if(keyList != null && keyList.length > 0){
for(String key:keyList){
Map<String, String> map = CommonUtils.getStorageBind(DictUtils.getDictValue("七牛云", "storage_type", "1"));
String ACCESS_KEY = null;
String SECRET_KEY = null;
String BUCKET = null;
if(map==null){
ACCESS_KEY = config.ACCESS_KEY;
SECRET_KEY = config.SECRET_KEY;
BUCKET = config.BUCKET;
}else{
ACCESS_KEY = map.get("ACCESS_KEY");
SECRET_KEY = map.get("SECRET_KEY");
BUCKET = map.get("BUCKET");
}
FileInfo fileInfo = getFileMags(key, map);
if(fileInfo != null && fileInfo.fsize > 0){
fileSize += (double)fileInfo.fsize/1048576;
keys.add(key);
}
}
}
if(keys != null && keys.size() > 0){
Map<String, String> map = CommonUtils.getStorageBind(DictUtils.getDictValue("七牛云", "storage_type", "1"));
String ACCESS_KEY = null;
String SECRET_KEY = null;
String BUCKET = null;
if(map==null){
ACCESS_KEY = config.ACCESS_KEY;
SECRET_KEY = config.SECRET_KEY;
BUCKET = config.BUCKET;
}else{
ACCESS_KEY = map.get("ACCESS_KEY");
SECRET_KEY = map.get("SECRET_KEY");
BUCKET = map.get("BUCKET");
}
//构造一个带指定Zone对象的配置类
Configuration cfg = new Configuration(Zone.zone1());
Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
BucketManager bucketManager = new BucketManager(auth, cfg);
try {
BucketManager.BatchOperations batchOperations = new BucketManager.BatchOperations();
batchOperations.addDeleteOp(BUCKET, keys.toArray(new String[keys.size()]));
Response response = bucketManager.batch(batchOperations);
BatchStatus[] batchStatusList = response.jsonToObject(BatchStatus[].class);
for (int i = 0; i < keys.size(); i++) {
BatchStatus status = batchStatusList[i];
String key = keys.get(i);
System.out.print(key + "\t");
if (status.code == 200) {
System.out.println("delete success");
} else {
System.out.println(status.data.error);
}
}
} catch (QiniuException ex) {
System.err.println(ex.response.toString());
}
}
return fileSize;
}*/
/**
* 描述:生成七牛云Key 生成策略:fileName + fileType
* @param fileName
* @return
* @since: 2017年10月14日 下午5:05:03
*/
public static String genKey(String fileName){
String fileType = fileName.substring(fileName.lastIndexOf("."), fileName.length());
String name = UUIDUtil.get16UUID() + fileType;
System.out.println(fileName+"----"+name);
return name;
}
/**
* 描述:格式转化
* @param resourceId
* @param ids
* @return
*/
public static Map<String,Object> handerMap(String resourceId,String ids){
Map<String,Object> map = new HashMap();
map.put("resourceId", StringUtils.isNoneBlank(resourceId) ? resourceId : "");
List<String> keyList = Arrays.asList(ids.split(","));
map.put("keyList", keyList);
return map;
}
/**
* 将图片转换成base64格式进行存储
* @return
*/
public static String encodeToString(BufferedImage image, String type) throws IOException {
String imageString = null;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
ImageIO.write(image, type, bos);
byte[] imageBytes = bos.toByteArray();
BASE64Encoder encoder = new BASE64Encoder();
imageString = encoder.encode(imageBytes);
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
return imageString;
}
/**
* 获取图片格式
* @param params
* @return
*/
public static String getSuffixNameInfo(MultipartFile params){
String result = "";
// 图片后缀
String suffixName = params.getOriginalFilename().substring(
params.getOriginalFilename().lastIndexOf("."));
if(suffixName.indexOf("png")>0){
result = "png";
}else if(suffixName.indexOf("jpg")>0){
result = "jpg";
}else if(suffixName.indexOf("jpeg")>0){
result = "jpeg";
}
return result;
}
/**
* base64 转MultipartFile
* @param base64
* @return
*/
public static MultipartFile base64ToMultipart(String base64) {
try {
// 注意base64是否有头信息,如:data:image/jpeg;base64,。。。
String[] baseStrs = base64.split(",");
BASE64Decoder decoder = new BASE64Decoder();
byte[] b = new byte[0];
b = decoder.decodeBuffer(baseStrs[0]);
for(int i = 0; i < b.length; ++i) {
if (b[i] < 0) {
b[i] += 256;
}
}
return new BASE64DecodedMultipartFile(b, baseStrs[0]);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
//获取文件信息
public static FileInfo getFileMags(String key, JSONObject jsonObject) {
String ACCESS_KEY = jsonObject.getString("ACCESS_KEY");
String SECRET_KEY = jsonObject.getString("SECRET_KEY");
String BUCKET = jsonObject.getString("BUCKET");
//构造一个带指定 Region 对象的配置类
Configuration cfg = new Configuration(Zone.zone1());
Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
BucketManager bucketManager = new BucketManager(auth, cfg);
FileInfo fileInfo = null;
try {
fileInfo = bucketManager.stat(BUCKET, key);
System.out.println(fileInfo.hash);
System.out.println(fileInfo.fsize);
System.out.println(fileInfo.mimeType);
System.out.println(fileInfo.putTime);
} catch (QiniuException ex) {
System.err.println(ex.response.toString());
}
return fileInfo;
}
/**
* 分片式,断点上传文件到七牛云
* @param jsonObject
* @return
* @throws Exception
*/
public static String uploadStream(JSONObject jsonObject) throws Exception{
String accessKey = jsonObject.getString("ACCESS_KEY");//ACCESS_KEY
String secretKey = jsonObject.getString("SECRET_KEY");//SECRET_KEY
String bucket = jsonObject.getString("BUCKET");//桶名称
String DOMAIN_URL = jsonObject.getString("DOMAIN_URL");//域名 例:http://www.baidu.com/
String ZIP_PATH = jsonObject.getString("ZIP_PATH");//上传文件到七牛云指定路径
String localFilePath = jsonObject.getString("filePath");//需要上传文件的本地路径
//构造一个带指定 Region 对象的配置类
Configuration cfg = new Configuration(Region.huabei());
cfg.resumableUploadAPIVersion = Configuration.ResumableUploadAPIVersion.V2;// 指定分片上传版本
cfg.resumableUploadMaxConcurrentTaskCount = 2; // 设置分片上传并发,1:采用同步上传;大于1:采用并发上传
//...其他参数参考类注释
//...生成上传凭证,然后准备上传
//String accessKey = "your access key";
//String secretKey = "your secret key";
//String bucket = "your bucket name";
//如果是Windows情况下,格式是 D:\\qiniu\\test.png
//String localFilePath = "/home/qiniu/test.mp4";
//默认不指定key的情况下,以文件内容的hash值作为文件名
File file = new File(localFilePath);
String key = ZIP_PATH + file.getName();//genKey(file.getOriginalFilename());
logger.info("图片:" + key);
//String key = null;
Auth auth = Auth.create(accessKey, secretKey);
String upToken = auth.uploadToken(bucket,key);
String mm = System.getenv("java.io.tmpdir");//"C:\\Users\\yys\\AppData\\Local\\Temp\\";//
String localTempDir = Paths.get(mm, bucket).toString();
try {
//设置断点续传文件进度保存目录
FileRecorder fileRecorder = new FileRecorder(localTempDir);
UploadManager uploadManager = new UploadManager(cfg, fileRecorder);
try {
Response response = uploadManager.put(localFilePath, key, upToken);
//解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
System.out.println(putRet.key);
System.out.println(putRet.hash);
return DOMAIN_URL + putRet.key;
} catch (QiniuException ex) {
Response r = ex.response;
System.err.println(r.toString());
try {
System.err.println(r.bodyString());
} catch (QiniuException ex2) {
//ignore
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
return null;
}
public static void main(String[] angs) throws Exception {
JSONObject jsonObject = new JSONObject();
jsonObject.put("ACCESS_KEY","123");
jsonObject.put("SECRET_KEY","123");
jsonObject.put("BUCKET","123");//同名称
jsonObject.put("DOMAIN_URL","http://域名/");
jsonObject.put("filePath","C:\\Users\\yygs\\Desktop\\chengxu\\sdfg\\dtyhf\\fhj\\测试v1.2.3.zip");
jsonObject.put("ZIP_PATH","home/fgh/edrtg/");//七牛云文件上传的指定路径
uploadStream(jsonObject);
}
}
maven pom需要引入的jar
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>[7.7.0, 7.10.99]</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.14.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>happy-dns-java</artifactId>
<version>0.1.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>