前言:当初自己搭建文件服务器后,有两个主要缺点,
第一, 自己的服务器网络带宽慢,app加载大点的文件太慢
第二, 文件地址依赖于服务器地址,测试阶段192.168.1.5过几天换wifi环境就变成192.168.44.2
第三,上传8M左右的图片,我的服务器带宽较小,再通过服务器转发到OSS还是太慢了
所以后来我选择了阿里云的OSS存储:我主要介绍两种web端直传的方式
第一种,web 端 直传到 OSS云存储
第二种,web 端 ---》自己的服务器---》OSS云存储
不懂web端直传,可以看这个博客文章(OSS上传文件的三种模式),
具体我这里不说明,可以看这个博客一看就懂:阿里云 OSS_小白一个-CSDN博客_阿里云oss ,这个有一定参考价值,可以先免费试用一个月,各种权限要给全哈
我将这部分写在另一篇:react native 直传 OSS
我一开始看也头疼,幸亏有同事帮忙,我粘贴一下,Java上使用OSS的代码逻辑
com.aliyun.oss
aliyun-sdk-oss
3.10.2
@Component
public class OssAliYun {
String endpoint = "你自己的";
String accessKeyId = "你自己的";
String accessKeySecret = "你自己的";
String bucketName = "你自己的";
private OSS ossClient;
@PostConstruct
private void init() {
// 创建OSSClient实例。
ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
}
/** 列举存储空间 */
public List listBuckets() {
return ossClient.listBuckets();
}
//上传文件,并返回文件的url
public String uploadOss(MultipartFile file){
byte [] byteArr = new byte[0];
try {
byteArr = file.getBytes();
} catch (IOException e) {
e.printStackTrace();
}
InputStream inputStream = new ByteArrayInputStream(byteArr);
//原文件名
String originFileName = file.getOriginalFilename();
//UUID + 文件后缀名(用户的命名都不用,因为里面可能包含特殊符号)
String newFileName = UUID.randomUUID()+originFileName.substring(originFileName.lastIndexOf('.'));
//从服务器将文件上传到OSS云存储上
handlePutObjectResult(newFileName,inputStream);
//得到OSS存储的地址
String urlSubject = getUrlSubject();
String url = urlSubject+newFileName;
return url;
}
//删除文件,判断是否存在
public void deleteObject(String fileName){
boolean isExist = ossClient.doesObjectExist(bucketName, fileName);
if(isExist){
ossClient.deleteObject(bucketName, fileName);
}
}
//简单上传文件
public PutObjectResult handlePutObjectResult(String key, InputStream input){
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, input);
return ossClient.putObject(putObjectRequest);
}
//获取文件的url(很简单,你查看文件详情的路径,就会发现它是由什么组成的)
public String getUrlSubject(){
return "https://"+bucketName+"."+"自己的";
}
}
新建一个AppRun的类,调用这个方法 ossAliYun.listBuckets(),看控制台打印,如果有,则生效
@Slf4j
@Component
public class AppRun implements ApplicationRunner {
@Autowired
OssAliYun ossAliYun;
@Override
public void run(ApplicationArguments args) throws Exception {
log.info(JSON.toJSONString(ossAliYun.listBuckets(), true));
}
}
前端用FormData 上传 图片(pic)、pdf(articlePdf)、音频(audio)
@PostMapping("/addOneArticle")
public ResultMsg addOneArticle(HttpServletRequest request){
//图片 和 pdf 文件
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest)request;
MultipartFile pic = multipartRequest.getFile("pic");
MultipartFile articlePdf = multipartRequest.getFile("articlePdf");
MultipartFile audio = multipartRequest.getFile("audio");
//获取pdf的url地址
String pdfUrl = getMultipartUrl(articlePdf);
String imgUrl = getMultipartUrl(pic);
String audioUrl = getMultipartUrl(audio);
return articleService.addOneArticle(title,articleSource,imgUrl,content,userId,timestamp,pdfUrl,audioUrl);
}
地址例子如下:http://192.168.1.5:8080/api/images/21c50dba-0a8c-4352-b4fc-1a6fcc987298.jpg
public String getMultipartUrl(MultipartFile file,HttpServletRequest request){
String url = "";
//判断是否为空
try {
boolean empty = file.isEmpty();
if(!empty){
// 获取原文件名称
String originalFileName = file.getOriginalFilename();
// 获取原文件的后缀
String fileSuffix = originalFileName.substring(originalFileName.lastIndexOf('.'));
// 重新生成文件名
originalFileName = UUID.randomUUID()+fileSuffix;
//将文件保存到指定位置
try{
file.transferTo(new File(filePath + originalFileName));
}catch (IOException e){
e.printStackTrace();
}
//返回图片的完整访问路径,这地方ip和端口可以改为动态获得,这样在部署到服务器上时无需改变,为了方便起见这里直接写死了
String localAddr = request.getLocalAddr();
//判断是不是 product生产环境
if(filePath.equals("/usr/java/uploadimage/")){
localAddr="47.242.216.94";
}
int localPort = request.getLocalPort();
url = "http://"+localAddr+":" + localPort + "/api/images/" + originalFileName;
}
}catch (Exception e){ //没有上传文件类型}
return url;
}
有用的话,麻烦点个赞,谢谢