前言:当初自己搭建文件服务器后,有两个主要缺点,

第一, 自己的服务器网络带宽慢,app加载大点的文件太慢

第二, 文件地址依赖于服务器地址,测试阶段192.168.1.5过几天换wifi环境就变成192.168.44.2

第三,上传8M左右的图片,我的服务器带宽较小,再通过服务器转发到OSS还是太慢了

所以后来我选择了阿里云的OSS存储:我主要介绍两种web端直传的方式

第一种,web 端 直传到 OSS云存储
第二种,web 端 ---》自己的服务器---》OSS云存储

不懂web端直传,可以看这个博客文章OSS上传文件的三种模式),

准备:在阿里云官网购买OSS云存储服务

具体我这里不说明,可以看这个博客一看就懂:阿里云 OSS_小白一个-CSDN博客_阿里云oss ,这个有一定参考价值,可以先免费试用一个月,各种权限要给全哈

一、Web端 直传到 OSS云存储

我将这部分写在另一篇:react native 直传 OSS

二、Web端--》自己的服务器 ---》OSS云存储

查看OSS的官方文档

我一开始看也头疼,幸亏有同事帮忙,我粘贴一下,Java上使用OSS的代码逻辑

(1)首先引入OSS的依赖

<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.10.2</version>
</dependency>

(2)新建一个OSS云存储的工具类

@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<Bucket> 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+"."+"自己的";
    }
}

(3)快速测试一下OSS是否搭建成功

新建一个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)

1. 后端代码接收如下

 @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);
    }
  
 

2. 调用 getMultipartUrl方法,返回url地址

地址例子如下: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;
    }

有用的话,麻烦点个赞,谢谢

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐