目的:储存一些图片和文件;
步骤:
1.整合jar包:有的使用的是3以上的版本,这个要看自己的springBoot版本
<!-- 阿里云对象存储服务 -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.8.3</version>
</dependency>
2.配置oss
3.工具类:
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.ObjectMetadata;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.io.InputStream;
/**
* @author zhangtonghao
* @create 2022-08-30 16:26
*/
@Component
public class OSSUtil {
private static Logger logger = LoggerFactory.getLogger(OSSUtil.class);
// private OSSClient ossClient;
@Value("${oss.endpoint.ext}")
private String endpoint;
@Value("${oss.endpoint.internal}")
private String internalEndpoint;
@Value("${oss.accessKeyId}")
private String accessKeyId;
@Value("${oss.accessKeySecret}")
private String accessKeySecret;
@Value("${oss.bucketName}")
private String bucketName;
/**
* 上传文件到阿里云,并生成url
*
* @param filedir (key)文件名(不包括后缀)
* @param in 文件字节流
* @return String 生成的文件url
*/
public String uploadToAliyun(String filedir, InputStream in, String fileName, boolean isRandomName) {
String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
if (isRandomName) {
fileName = UUIDGenerator.generateCommonUUID() + "." + suffix;
}
logger.debug("------------>文件名称为: " + fileName);
OSSClient ossClient = new OSSClient(internalEndpoint, accessKeyId, accessKeySecret);
String url = null;
try {
// 创建上传Object的Metadata
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentLength(in.available());
objectMetadata.setCacheControl("no-cache");// 设置Cache-Control请求头,表示用户指定的HTTP请求/回复链的缓存行为:不经过本地缓存
objectMetadata.setHeader("Pragma", "no-cache");// 设置页面不缓存
objectMetadata.setContentType(getcontentType(suffix));
objectMetadata.setContentDisposition("inline;filename=" + fileName);
// 上传文件
ossClient.putObject(bucketName, filedir + "/" + fileName, in, objectMetadata);
url = buildUrl(filedir + "/" + fileName);
} catch (IOException e) {
logger.error("error", e);
} finally {
ossClient.shutdown();
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
logger.error("error", e);
}
}
return url;
}
private String buildUrl(String fileDir) {
StringBuffer url = new StringBuffer();
if (org.apache.commons.lang3.StringUtils.isEmpty(bucketName)) {
logger.error("bucketName为空");
return null;
}
if (org.apache.commons.lang3.StringUtils.isEmpty(endpoint)) {
logger.error("endpoint为空");
return null;
}
if (StringUtils.isEmpty(endpoint)) {
logger.error("上传文件目录为空");
return null;
}
url.append("https://").append(bucketName).append(".").append(endpoint).append("/").append(fileDir);
return url.toString();
}
/**
* 删除图片
*
* @param key
*/
public void deletePicture(String key) {
OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
ossClient.deleteObject(bucketName, key);
ossClient.shutdown();
}
/**
* Description: 判断OSS服务文件上传时文件的contentType
*
* @param suffix 文件后缀
* @return String HTTP Content-type
*/
public String getcontentType(String suffix) {
if (suffix.equalsIgnoreCase("bmp")) {
return "image/bmp";
} else if (suffix.equalsIgnoreCase("gif")) {
return "image/gif";
} else if (suffix.equalsIgnoreCase("jpeg") || suffix.equalsIgnoreCase("jpg")) {
return "image/jpeg";
} else if (suffix.equalsIgnoreCase("png")) {
return "image/png";
} else if (suffix.equalsIgnoreCase("html")) {
return "text/html";
} else if (suffix.equalsIgnoreCase("txt")) {
return "text/plain";
} else if (suffix.equalsIgnoreCase("vsd")) {
return "application/vnd.visio";
} else if (suffix.equalsIgnoreCase("pptx") || suffix.equalsIgnoreCase("ppt")) {
return "application/vnd.ms-powerpoint";
} else if (suffix.equalsIgnoreCase("docx") || suffix.equalsIgnoreCase("doc")) {
return "application/msword";
} else if (suffix.equalsIgnoreCase("xls") || suffix.equalsIgnoreCase("xlsx")) {
return "application/vnd.ms-excel";
} else if (suffix.equalsIgnoreCase("xml")) {
return "text/xml";
} else if (suffix.equalsIgnoreCase("mp3")) {
return "audio/mp3";
} else if (suffix.equalsIgnoreCase("amr")) {
return "audio/amr";
} else if (suffix.equalsIgnoreCase("pdf")) {
return "application/pdf";
} else {
return "text/plain";
}
}
}
4.使用:
//注入oss工具类
@Autowired
private OSSUtil ossUtil;
/**
* 授权文件上传
*
* @param file
* @return
*/
@PostMapping("/upload")
public Result<String> upload(@RequestParam("file") MultipartFile file) {
if (file.isEmpty()) {
return Result.error(ErrorCodeEnum.REQUEST_API_ERROR.getCode(),
ErrorCodeEnum.REQUEST_API_ERROR.getMsg());
}
String fileName = file.getOriginalFilename();
String url = null;
try {
url = ossUtil.uploadToAliyun("card/img",
new ByteArrayInputStream(file.getBytes()), fileName, true);
} catch (IOException e) {
logger.error("上传产品图片失败", e);
return Result.error(ErrorCodeEnum.REQUEST_API_ERROR.getCode(),
ErrorCodeEnum.REQUEST_API_ERROR.getMsg());
}
return Result.success(url);
}
5.注意事项:下面有的会出现,但是我并没有
spring boot 会默认加载org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration这个类,
而DataSourceAutoConfiguration类使用了@Configuration注解向spring注入了dataSource bean,又因为项目(oss模块)中并没有关于dataSource相关的配置信息,所以当spring创建dataSource bean时因缺少相关的信息就会报错。
解决办法:
方法1、在@SpringBootApplication注解上加上exclude,解除自动加载DataSourceAutoConfiguration
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
6.延伸
一般的文章到上面就结束了,不过我这里还想加些实践的。
oss常用工具:oss-browser
相应的配置信息在配置中取即可,要注意的路径:oss://+bucketName
业务:一般我们上传的时候bucketName都是给好的,像一些什么没有bucketName还需要创建的其实都是多此一举,没有bucket直接找到运维同事创建一个即可。而在公司操作中大部分都是自己创建文件夹名称:比如传参中用户ID+设备id+文件属性+文件类型,其实就和redis创建key一样,网上的不要照抄,自己思考就好,下面例子可以供参考。
//生成文件key
public String buildFileKey(String folder, String origFileName, Integer audioType, boolean isUseOrigFileName) {
if (origFileName == null) {
return null;
}
if (CommonConstants.AudioType.STAFF.equals(audioType) || CommonConstants.AudioType.CUSTOMER.equals(audioType)) {
folder = audioFolder + "/" + folder;
} else if (CommonConstants.AudioType.INSPECTION.equals(audioType)) {
folder = inspectionFolder + "/" + folder;
} else if (CommonConstants.AudioType.MATERIAL.equals(audioType)) {
folder = materialFolder + "/" + folder;
}
String filePath = DateUtil.getNowDateString();
if (isUseOrigFileName) {
String fileKey = folder + "/" + filePath + "/" + origFileName;
logger.debug("file key: " + fileKey);
return fileKey;
}
int index = origFileName.lastIndexOf(".");
String fileExtName = index >= 0 ? origFileName.substring(index) : "";
String fileName = java.util.UUID.randomUUID().toString().replaceAll("-", "");
String fileKey = folder + "/" + filePath + "/" + fileName + fileExtName;
return fileKey;
}
/**
* 创建文件名称
* @param audioRecordVO
* @return
*/
private String buildFileKey(AudioRecordVO audioRecordVO) {
StringBuffer fileName = new StringBuffer();
fileName.append(audioRecordVO.getStaffId());
fileName.append("-");
fileName.append(audioRecordVO.getAudioType());
fileName.append("-");
fileName.append(audioRecordVO.getDeviceId());
fileName.append("-");
fileName.append(DateUtil.formatTimeToString(audioRecordVO.getFileStartTime(), DateUtil.TIME_FORMAT_NO_SPACE));
fileName.append(".");
fileName.append(audioRecordVO.getFileType());
audioRecordVO.setFileName(aliyunStorageService.buildFileKey(appKey, fileName.toString(),audioRecordVO
.getAudioType(), true));
return audioRecordVO.getFileName();
}
创作不易,如果这篇文章对你有用,请点个赞谢谢♪(・ω・)ノ!
网友评论