许多图片,视频,文件基本上都是上传到oss,那么该如何上传呢?
话不多说,上代码。
引入依赖:
<!-- OSS SDK 相关依赖 -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.8.3</version>
</dependency>
第一步配置yml文件(根据自己的需求进行配置):
oss:
file:
endpoint: # oss对外服务的访问域名
accessKeyId: # 访问身份验证中用到用户标识
sccessKeySecret: # 用户用于加密签名字符串和oss用来验证签名字符串的密钥
bucketName: #桶样子的名称
#文件路径
urlPrefix:
第二步两个帮助类AliyunOssConfig
package com.ruoyi.fazhi.config;
import com.aliyun.oss.OSSClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.io.Serializable;
/**
* @desc
*
* @author 团子
* @date 2019-07-31 11:31
*/
@Configuration
public class AliyunOssConfig implements Serializable {
@Value("${oss.file.endpoint}")
private String endpoint;
@Value("${oss.file.accessKeyId}")
private String accessKeyId;
@Value("${oss.file.sccessKeySecret}")
private String accessKeySecret;
@Value("${oss.file.bucketName}")
private String bucketName;
@Value("${oss.file.urlPrefix}")
private String urlPrefix;
@Bean
public OSSClient oSSClient() {
return new OSSClient(endpoint, accessKeyId, accessKeySecret);
}
@Override
public String toString() {
return "AliyunOssConfig{" +
"endpoint='" + endpoint + '\'' +
", accessKeyId='" + accessKeyId + '\'' +
", accessKeySecret='" + accessKeySecret + '\'' +
", bucketName='" + bucketName + '\'' +
", urlPrefix='" + urlPrefix + '\'' +
'}';
}
public String getEndpoint() {
return endpoint;
}
public void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}
public String getAccessKeyId() {
return accessKeyId;
}
public void setAccessKeyId(String accessKeyId) {
this.accessKeyId = accessKeyId;
}
public String getAccessKeySecret() {
return accessKeySecret;
}
public void setAccessKeySecret(String accessKeySecret) {
this.accessKeySecret = accessKeySecret;
}
public String getBucketName() {
return bucketName;
}
public void setBucketName(String bucketName) {
this.bucketName = bucketName;
}
public String getUrlPrefix() {
return urlPrefix;
}
public void setUrlPrefix(String urlPrefix) {
this.urlPrefix = urlPrefix;
}
}
第二个OssUtil
package com.ruoyi.fazhi.util;
import com.alibaba.fastjson2.JSONObject;
import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.ObjectMetadata;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.MimeTypeUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.fazhi.config.AliyunOssConfig;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* @Description: 阿里云 oss 上传工具类(高依赖版)
* @Author: @author jiangpengcheng
* @Date: 2020/7/15
*/
public class OssUtil {
public OssUtil(){}
@Autowired
private AliyunOssConfig ossConfig;
/**
* oss 工具客户端
*/
private volatile static OSSClient ossClient = null;
/**
* 上传文件至阿里云 OSS
* 文件上传成功,返回文件完整访问路径
* 文件上传失败,返回 null
* @author jiangpengcheng
* @param ossConfig oss 配置信息
* @param file 待上传文件
* @return oss 中的相对文件路径
*/
public static String upload(AliyunOssConfig ossConfig, MultipartFile file){
initOSS(ossConfig);
Map<String,String> url=new HashMap<>();
StringBuilder fileUrl = new StringBuilder();
try {
String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.'));
//检查文件类型图片和视频分开
String fileName=null;
ObjectMetadata objectMetadata = new ObjectMetadata();
final boolean imgAllow = FileUploadUtils.isAllowedExtension(FileUploadUtils.getExtension(file), MimeTypeUtils.IMAGE_EXTENSION);
final boolean videoAllow = FileUploadUtils.isAllowedExtension(FileUploadUtils.getExtension(file), MimeTypeUtils.VIDEO_EXTENSION);
if(imgAllow){
fileName = "images/"+DateUtils.datePath() + "/" + IdUtils.fastUUID()+ suffix;
objectMetadata.setContentType(contentType(FileUploadUtils.getExtension(file)));
url.put("fileName",fileName);
url.put("type","img");
}
if(videoAllow){
fileName = "video/"+DateUtils.datePath() + "/" + IdUtils.fastUUID()+ suffix;
objectMetadata.setContentType(contentType(FileUploadUtils.getExtension(file)));
url.put("fileName",fileName);
url.put("type","video");
}
fileUrl = fileUrl.append(ossConfig.getUrlPrefix()+fileName);
System.out.println(fileUrl+"-----------------");
url.put("fileUrl",fileUrl.toString());
// 2.上传文件到OSS
InputStream inputStream = file.getInputStream();
objectMetadata.setContentLength(inputStream.available());
objectMetadata.setCacheControl("no-cache");
ossClient.putObject(ossConfig.getBucketName(), fileUrl.toString(),inputStream,objectMetadata);
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
return null;
}
return fileUrl.toString();
}
/**
* 初始化 oss 客户端
* @param ossConfig
* @return
*/
private static OSSClient initOSS(AliyunOssConfig ossConfig) {
if (ossClient == null ) {
synchronized (AliyunOssConfig.class) {
if (ossClient == null) {
ossClient = new OSSClient(ossConfig.getEndpoint(),
new DefaultCredentialProvider(ossConfig.getAccessKeyId(), ossConfig.getAccessKeySecret()),
new ClientConfiguration());
}
}
}
return ossClient;
}
/**
* @date 2016年12月29日上午11:17:11
* @param FilenameExtension
* @return String
* @Des:判断OSS服务文件上传时文件的contentType
*/
public static String contentType(String FilenameExtension){
if(FilenameExtension.equals("BMP")||FilenameExtension.equals("bmp")){return "image/bmp";}
if(FilenameExtension.equals("GIF")||FilenameExtension.equals("gif")){return "image/gif";}
if(FilenameExtension.equals("JPEG")||FilenameExtension.equals("jpeg")||
FilenameExtension.equals("JPG")||FilenameExtension.equals("jpg")||
FilenameExtension.equals("PNG")||FilenameExtension.equals("png")){return "image/jpeg";}
if(FilenameExtension.equals("HTML")||FilenameExtension.equals("html")){return "text/html";}
if(FilenameExtension.equals("TXT")||FilenameExtension.equals("txt")){return "text/plain";}
if(FilenameExtension.equals("VSD")||FilenameExtension.equals("vsd")){return "application/vnd.visio";}
if(FilenameExtension.equals("PPTX")||FilenameExtension.equals("pptx")||
FilenameExtension.equals("PPT")||FilenameExtension.equals("ppt")){return "application/vnd.ms-powerpoint";}
if(FilenameExtension.equals("DOCX")||FilenameExtension.equals("docx")||
FilenameExtension.equals("DOC")||FilenameExtension.equals("doc")){return "application/msword";}
if(FilenameExtension.equals("XML")||FilenameExtension.equals("xml")){return "text/xml";}
if(FilenameExtension.equals("MP4")||FilenameExtension.equals("mp4")||FilenameExtension.equals("flv")){return "video/mp4";}
return "text/html";
}
/**
* 根据前台传过来的文件地址 删除文件
* @author jiangpengcheng
* @param objectName
* @param ossConfig
* @return
*/
public static AjaxResult delete(String objectName, AliyunOssConfig ossConfig) {
//将完整路径替换成 文件地址 因为yml里的url有了地址链接https: //oos-all.oss-cn-shenzhen.aliyuncs.com/
// 如果再加上地址 那么又拼接了 所以删除不了 要先把地址替换为 jpc/2020-07-16/1594857669731-51d057b0-9778-4aed.png
String fileName = objectName.replace("https://oos-all.oss-cn-shenzhen.aliyuncs.com/", "");
System.out.println(fileName+"******************************");
// 根据BucketName,objectName删除文件
ossClient.deleteObject(ossConfig.getBucketName(), fileName);
return AjaxResult.success("删除成功",fileName);
}
}
配置完成Controller层代码(调用)上传后返回的路径是可以直接前端显示的
@Value("${wx.miniapp.configs[0].appid}")
private String appId;
@Value("${wx.miniapp.configs[0].secret}")
private String secret;
@Autowired
private AliyunOssConfig ossConfig;
@Autowired
private OSS ossClient;
@ApiOperation(value = "图片和视频上传oss接口")
@PostMapping("/image")
public AjaxResult upload(@RequestParam("file") MultipartFile multipartFile) {
String originalFilename = multipartFile.getOriginalFilename();
String s = StringUtils.substringAfter(originalFilename, ".");
if (!"jpg".equals(s)&&!"jpeg".equals(s)&&!"png".equals(s)&&!"gif".equals(s)&&!"doc".equals(s)&&!"docx".equals(s)&&!"xls".equals(s)&&!"xlsx".equals(s)&&!"ppt".equals(s)&&!"pptx".equals(s)&&!"mp4".equals(s)&&!"avi".equals(s)&&!"mov".equals(s)&&!"mp3".equals(s)){
return AjaxResult.error("文件格式不正确请上传,'jpg', 'png', 'jpeg', 'gif', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'mp4', 'avi', 'mov', 'mp3'");
}
//获取获取返回的url
String upload = OssUtil.upload(ossConfig, multipartFile);
if(upload==null){
AjaxResult.error("403","上传出错");
}
// 设置URL过期时间为5年 3600l* 1000*24*365*10
Date expiration = new Date(System.currentTimeMillis()+ 3600L * 1000 * 24 * 365*5);
// 生成URL
URL url = ossClient.generatePresignedUrl(ossConfig.getBucketName(), upload, expiration);
// //去除URL的参数 这个私有获取不到
// String tmp = url.toString().split("\\?")[0];
// int index = tmp.lastIndexOf("/") + 1;
return AjaxResult.success("200",url);
}
上传写完我们来看下载直接上代码
package com.ruoyi.fazhi.controller;
import java.io.*;
import java.net.URLDecoder;
import java.net.URLEncoder;
import javax.servlet.http.HttpServletResponse;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.CopyObjectRequest;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import com.aliyun.oss.model.ObjectMetadata;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.aliyun.oss.OSS;
import com.aliyun.oss.model.OSSObject;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value = "/oss")
public class ossController {
private final Logger logger = LoggerFactory.getLogger(ossController.class);
@Value("${oos.file.endpoint}")
private String endpoint;
@Value("${oos.file.accessKeyId}")
private String accessKeyId;
@Value("${oos.file.sccessKeySecret}")
private String accessKeySecret;
@Value("${oos.file.bucketName}")
private String bucketName;
@Value("${oos.file.urlPrefix}")
private String folder;
/**
* 下载OSS服务器的文件
*
*/
@PostMapping(value = "/downOSSFile")
public void getFileToZip(@RequestBody Long ids,HttpServletResponse response) throws IOException {
Collect collect = collectService.selectCollectByCollectId(ids);
String collectImage = collect.getCollectImage();
WxUser WxUser = WxUserService.selectWxUserByOpenId(collect.getOpenid());
String name ="";
if (xphWxUser==null){
name="暂无此用户";
}
String[] split = collectImage.split(",");
List<String> fileNames = new ArrayList<>();
for (String s : split) {
String tmp = s.split("\\?")[0];
//下载只需要域名后面的路径就可以了所以存入数据库的域名需要去除
String replace = tmp.replace("文件上传的域名", "");
fileNames.add(replace);
}
OSS ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
//压缩包名称
String zipName = name+".zip";
//创建临时文件
File zipFile = File.createTempFile("test", ".zip");
FileOutputStream fileOutputStream = new FileOutputStream(zipFile);
/**
* 作用是为任何outputstream产生校验和
* 第一个参数是制定产生校验和的输出流,第二个参数是指定checksum类型(Adler32(较快)和CRC32两种)
*/
CheckedOutputStream cos = new CheckedOutputStream(fileOutputStream, new Adler32());
//用于将数据压缩成zip文件格式
ZipOutputStream zos = new ZipOutputStream(cos);
for (String fileName : fileNames) {
//获取object,返回结果ossObject对象
OSSObject ossObject = ossClient.getObject(bucketName, fileName);
//读取object内容,返回
InputStream inputStream = ossObject.getObjectContent();
// 对于每一个要被存放到压缩包的文件,都必须调用ZipOutputStream对象的putNextEntry()方法,确保压缩包里面文件不同名
zos.putNextEntry(new ZipEntry(fileName));
int bytesRead = 0;
// 向压缩文件中输出数据
while ((bytesRead = inputStream.read()) != -1) {
zos.write(bytesRead);
}
inputStream.close();
zos.closeEntry(); // 当前文件写完,定位为写入下一条项目
}
zos.close();
response.setContentType("application/octet-stream;charset=utf-8");
response.setHeader("Content-Disposition", "attachment;filename=" + zipName);
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();
}
}
调用这个接口就可以下载到浏览器了(因为每次下载只能下载一个文件,多文件怎么下载呢?)
放在压缩包里面就行了。
前端代码
//下载按钮
<el-button
@click="handleUpdates(scope.row)"
>下载</el-button>
/** 下载按钮操作 */
handleUpdates(row) {
const ids = row.collectId;
console.log(ids);
this.percentage = 0;
this.progressShow=true;
//发起请求
axios({
url: process.env.VUE_APP_BASE_API+"/oss/downOSSFile",
method: "post",
data:ids,
responseType: "blob",
headers: { 'Authorization': 'Bearer ' + getToken() },
//xml返回数据的钩子函数,可以用来获取数据的进度 具体可查看axios的官网
}).then(res => {
if (res.status !== 200) {
this.$message.error("文件下载失败,请稍后重试!");
return false;
}
//blob返回的是一个 base64 格式的文件流
let blob = new Blob([res.data], {
//编译文件为xlsx类型。 具体可查看 blob 方法定义的类型
type: "application/zip"
})
//编译文件
if (window.navigator && window.navigator.meSaveOrOpenBlob) {
window.navigator.meSaveOrOpenBlob(blob, )
} else {
// 非ie的下载
const link = document.createElement('a');
const body = document.querySelector('body');
link.href = window.URL.createObjectURL(blob);
link.download =row.name+'.zip'; // 下载的文件名
// fix Firefox
link.style.display = 'none';
body.appendChild(link);
link.click();
body.removeChild(link);
window.URL.revokeObjectURL(link.href);
}
//编译文件完成后,进度条展示为100%100
this.percentage = 100;
this.progressShow = false; // 关闭进度条显示层
})
}
这样就进行压缩下载了。
有不足的地方请多多指教。