一、阿里云账号及OSS配置

购买资源包,可按年按月付费,也可按照流量计费。根据自己需要购买。

oss上传 iOS oss上传图片_java

1、创建Bucket--创建Bucket(注意:本次选择的华北2,不同地区的代码对接中配置不一样)

oss上传 iOS oss上传图片_上传_02

存储类型:

标准存储:高可用、高性能的,基本的数据访问,用于正常网站访问,保证数据量大的网站读写能力。

低频访问存储:一般用于上传的东西很少有人访问,用于自己的数据存储和学习,收费低于标准存储

归档存储:用于数据归档,基本出问题才需要去查看的数据,收费低于低频访问存储。

冷归档存储:用于数据归档,基本不访问,收费低于归档存储。

oss上传 iOS oss上传图片_上传_03

 读写权限选择公共读:写入需要配置参数进行授权写入,上传的资源,所有人都能通过链接访问。

oss上传 iOS oss上传图片_存储空间_04

点击Bucket列表名称,进入Bucket存储目录,添加目录名称

存储路径(FOLDER)

oss上传 iOS oss上传图片_存储空间_05

准备配置的秘钥(ACCESS_KEY_ID、ACCESS_KEY_SECRET)Bucket名称(BACKET_NAME)、存储路径(FOLDER)、外网域名(ENDPOINT)

秘钥(ACCESS_KEY_ID、ACCESS_KEY_SECRET)--老版本

oss上传 iOS oss上传图片_存储空间_06

Bucket名称(BACKET_NAME)

oss上传 iOS oss上传图片_存储空间_07

 外网域名

oss上传 iOS oss上传图片_上传_08

二、代码配置OSSClientConstants 基本参数配置类,此处也可设置到配置项中

oss上传 iOS oss上传图片_存储空间_09

Jar包引入

<!-- 阿里云oss --> <dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>3.0.0</version> </dependency>

AliyunOSSClientUtil工具类
package com.central.file.config.aliyun;



import com.alibaba.nacos.client.naming.utils.StringUtils;
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.Bucket;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import com.central.common.utils.DateUtils;
import com.central.file.utils.UUIDUtils;
import com.sun.deploy.net.HttpUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;



/**
 * @author sang
 * @class:AliyunOSSClientUtil
 * @descript:java使用阿里云OSS存储对象上传图片
 * @date:2022年3月16日 下午5:58:08
 */
public class AliyunOSSClientUtil{

    private static final Logger log = LoggerFactory.getLogger(HttpUtils.class);

    private long bytesWritten = 0;
    private long totalBytes = -1;
    private boolean succeed = false;

    private static String number;


    //阿里云API的内或外网域名
    private static String ENDPOINT;
    //阿里云API的密钥Access Key ID
    private static String ACCESS_KEY_ID;
    //阿里云API的密钥Access Key Secret
    private static String ACCESS_KEY_SECRET;
    //阿里云API的bucket名称
    private static String BACKET_NAME;
    //阿里云API的文件夹名称
    private static String FOLDER;

    //初始化
    /* private static  OSSClient ossClient=AliyunOSSClientUtil.getOSSClient();*/
    //初始化属性
    static {
        ENDPOINT = OSSClientConstants.ENDPOINT;
        ACCESS_KEY_ID = OSSClientConstants.ACCESS_KEY_ID;
        ACCESS_KEY_SECRET = OSSClientConstants.ACCESS_KEY_SECRET;
        BACKET_NAME = OSSClientConstants.BACKET_NAME;
        FOLDER = OSSClientConstants.FOLDER;
    }

    /**
     * 获取阿里云OSS客户端对象
     *
     * @return ossClient
     */
    public static OSSClient getOSSClient() {
        ClientBuilderConfiguration conf = new ClientBuilderConfiguration(); // 连接空闲超时时间,超时则关闭
        conf.setIdleConnectionTime(1000); // 在这里可以做一些配置,比如超时时间、最大连
        return new OSSClient(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
    }

    /**
     * 创建存储空间
     *
     * @param ossClient  OSS连接
     * @param bucketName 存储空间
     * @return
     */
    public static String createBucketName(OSSClient ossClient, String bucketName) {
        //存储空间
        final String bucketNames = bucketName;
        if (!ossClient.doesBucketExist(bucketName)) {
            //创建存储空间
            Bucket bucket = ossClient.createBucket(bucketName);
            log.info("创建存储空间成功");
            return bucket.getName();
        }
        return bucketNames;
    }

    /**
     * 删除存储空间buckName
     *
     * @param ossClient  oss对象
     * @param bucketName 存储空间
     */
    public static void deleteBucket(OSSClient ossClient, String bucketName) {
        ossClient.deleteBucket(bucketName);
        log.info("删除" + bucketName + "Bucket成功");
    }

    /**
     * 创建模拟文件夹
     *
     * @param ossClient  oss连接
     * @param bucketName 存储空间
     * @param folder     模拟文件夹名如"qj_nanjing/"
     * @return 文件夹名
     */
    public static String createFolder(OSSClient ossClient, String bucketName, String folder) {
        //文件夹名
        final String keySuffixWithSlash = folder;
        //判断文件夹是否存在,不存在则创建
        if (!ossClient.doesObjectExist(bucketName, keySuffixWithSlash)) {
            //创建文件夹
            ossClient.putObject(bucketName, keySuffixWithSlash, new ByteArrayInputStream(new byte[0]));
            log.info("创建文件夹成功");
            //得到文件夹名
            OSSObject object = ossClient.getObject(bucketName, keySuffixWithSlash);
            String fileDir = object.getKey();
            return fileDir;
        }
        return keySuffixWithSlash;
    }

    /**
     * 根据key删除OSS服务器上的文件
     *
     * @param ossClient  oss连接
     * @param bucketName 存储空间
     * @param folder     模拟文件夹名 如"qj_nanjing/"
     * @param key        Bucket下的文件的路径名+文件名 如:"upload/cake.jpg"
     */
    public static void deleteFile(OSSClient ossClient, String bucketName, String folder, String key) {
        ossClient.deleteObject(bucketName, folder + key);
        log.info("删除" + bucketName + "下的文件" + folder + key + "成功");
    }


    //测试
    public void main(String[] args) {
        //初始化OSSClient
        OSSClient ossClient = AliyunOSSClientUtil.getOSSClient();
        //上传文件
        String imgPath = "C:\\Users\\yaya\\Pictures\\内控项目图片\\yuan.png";
        String[] file = imgPath.split(",");
        for (String filename : file) {
            //System.out.println("filename:"+filename);
            File filess = new File(filename);
            String md5key = this.uploadObject2OSS(ossClient, filess, BACKET_NAME, FOLDER).get("resultStr").toString();
            log.info("上传后的文件MD5数字唯一签名:" + md5key);
            //上传后的文件MD5数字唯一签名:40F4131427068E08451D37F02021473A
        }
    }

    /**
     * 上传图片至OSS
     *
     * @param ossClient  oss连接
     * @param file       上传文件(文件全路径如:D:\\image\\cake.jpg)
     * @param bucketName 存储空间
     * @param folder     模拟文件夹名 如"qj_nanjing/"
     * @return Map 返回的唯一MD5数字签名 以及 对应的上传到文件的key
     */
    public Map<String, Object> uploadObject2OSS(OSSClient ossClient, File file, String bucketName, String folder) {
        String resultStr = null;
        Map map = new HashMap();
        try {
            //以输入流的形式上传文件
            InputStream is = new FileInputStream(file);
            //文件名
            String fileName = file.getName();
            fileName.replace("/", "").replace("\\", "");
            fileName = fileName.substring(0, fileName.lastIndexOf("."))
                    + UUIDUtils.getUUID() + fileName.substring(fileName.lastIndexOf("."));
            // key的组成
            /*String newFileName= UUID.randomUUID().toString();*/
            //文件大小
            Long fileSize = file.length();
            //创建上传Object的Metadata
            ObjectMetadata metadata = new ObjectMetadata();
            //上传的文件的长度
            metadata.setContentLength(is.available());
            //指定该Object被下载时的网页的缓存行为
            metadata.setCacheControl("no-cache");
            //指定该Object下设置Header
            metadata.setHeader("Pragma", "no-cache");
            //指定该Object被下载时的内容编码格式
            metadata.setContentEncoding("utf-8");
            //文件的MIME,定义文件的类型及网页编码,决定浏览器将以什么形式、什么编码读取文件。如果用户没有指定则根据Key或文件名的扩展名生成,
            //如果没有扩展名则填默认值application/octet-stream
            metadata.setContentType(this.getContentType(fileName));
            //指定该Object被下载时的名称(指示MINME用户代理如何显示附加的文件,打开或下载,及文件名称)
            metadata.setContentDisposition("filename/filesize=" + fileName + "/" + fileSize + "Byte.");
            //上传文件   (上传文件流的形式)
            PutObjectResult putResult = ossClient.putObject(bucketName, fileName, is, metadata);
            //解析结果
            System.out.println(this.getUrl(fileName));
            resultStr = putResult.getETag();
            map.put("resultStr", resultStr);
            map.put("imageUrl", fileName);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("上传阿里云OSS服务器异常." + e.getMessage(), e);
        }
        return map;
    }

    /**
     * 通过文件名判断并获取OSS服务文件上传时文件的contentType
     *
     * @param fileName 文件名
     * @return 文件的contentType
     */
    public  String getContentType(String fileName) {
        //文件的后缀名
        String fileExtension = fileName.substring(fileName.lastIndexOf("."));
        if (".bmp".equalsIgnoreCase(fileExtension)) {
            return "image/bmp";
        }
        if (".gif".equalsIgnoreCase(fileExtension)) {
            return "image/gif";
        }
        if (".jpeg".equalsIgnoreCase(fileExtension) || ".jpg".equalsIgnoreCase(fileExtension) || ".png".equalsIgnoreCase(fileExtension)) {
            return "image/jpeg";
        }
        if (".html".equalsIgnoreCase(fileExtension)) {
            return "text/html";
        }
        if (".txt".equalsIgnoreCase(fileExtension)) {
            return "text/plain";
        }
        if (".vsd".equalsIgnoreCase(fileExtension)) {
            return "application/vnd.visio";
        }
        if (".ppt".equalsIgnoreCase(fileExtension) || "pptx".equalsIgnoreCase(fileExtension)) {
            return "application/vnd.ms-powerpoint";
        }
        if (".doc".equalsIgnoreCase(fileExtension) || "docx".equalsIgnoreCase(fileExtension)) {
            return "application/msword";
        }
        if (".xml".equalsIgnoreCase(fileExtension)) {
            return "text/xml";
        }
        if (".flv".equalsIgnoreCase(fileExtension)) {
            return "video/x-flv";
        }
        if (".mp3".equalsIgnoreCase(fileExtension)) {
            return "audio/mpeg";
        }
        if (".mp4".equalsIgnoreCase(fileExtension)) {
            return "video/mp4";
        }

        //默认返回类型
        return "image/jpeg";
    }

    //通过key获取到上传文件的地址
    public String getUrl(String key) {
        OSSClient ossClient = AliyunOSSClientUtil.getOSSClient();
        // 设置URL过期时间为10年  3600l* 1000*24*365*10
        Date expiration = new Date(new Date().getTime() + 3600l * 1000 * 24 * 365 * 10);
        // 生成URL
        URL url = ossClient.generatePresignedUrl(BACKET_NAME, key, expiration);
        if (url != null) {
            return url.toString().split("\\?")[0];
        }
        return null;
    }


    /**
     * 上传图片至OSS
     *
     * @param ossClient                    oss连接
     * @param (文件全路径如:D:\\image\\cake.jpg)
     * @param bucketName                   存储空间
     * @param folder                       模拟文件夹名 如"qj_nanjing/"
     * @return Map 返回的唯一MD5数字签名 以及 对应的上传到文件的key
     */
    public  Map<String, Object> uploadObject2OSSnew(OSSClient ossClient, MultipartFile f, String bucketName, String folder, String bisType,String sessionKey) {
        number = sessionKey;
        String resultStr = null;
        Map map = new HashMap();
        try {
            //以输入流的形式上传文件
            InputStream is = f.getInputStream();
            //文件名
            String fileName = f.getOriginalFilename();
            if (fileName.lastIndexOf(".") == -1) {
                fileName = DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD) + "/" + Calendar.getInstance().getTimeInMillis() + ".jpg";
            }
            fileName.replace("/", "").replace("\\", "");
            if ("".equals(fileName)) {
                fileName = DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD) + "/" + fileName.substring(0, fileName.lastIndexOf(".")) + Calendar.getInstance().getTimeInMillis() + ".jpg";
            } else {
                fileName = DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD) + "/" + fileName.substring(0, fileName.lastIndexOf(".")) + Calendar.getInstance().getTimeInMillis() + fileName.substring(fileName.lastIndexOf("."), fileName.length());
            }
            if (StringUtils.isNotEmpty(bisType)) {
                fileName = bisType + "/" + fileName;
            }
            if(StringUtils.isNotEmpty(folder)){
                fileName = folder + "/" + fileName;
            }

            // key的组成
            /*String newFileName= UUID.randomUUID().toString();*/
            //文件大小
            Long fileSize = f.getSize();
            //创建上传Object的Metadata
            ObjectMetadata metadata = new ObjectMetadata();
            //上传的文件的长度
            metadata.setContentLength(is.available());
            //指定该Object被下载时的网页的缓存行为
            metadata.setCacheControl("no-cache");
            //指定该Object下设置Header
            metadata.setHeader("Pragma", "no-cache");
            //指定该Object被下载时的内容编码格式
            metadata.setContentEncoding("utf-8");
            //文件的MIME,定义文件的类型及网页编码,决定浏览器将以什么形式、什么编码读取文件。如果用户没有指定则根据Key或文件名的扩展名生成,
            //如果没有扩展名则填默认值application/octet-stream
            metadata.setContentType(f.getContentType());
            //指定该Object被下载时的名称(指示MINME用户代理如何显示附加的文件,打开或下载,及文件名称)
            metadata.setContentDisposition("filename/filesize=" + fileName + "/" + fileSize + "Byte.");
            //上传文件   (上传文件流的形式)
            PutObjectResult putResult = ossClient.putObject(bucketName, fileName, is, metadata);
            // 带进度条的上传。
            //解析结果
            System.out.println(getUrl(fileName));
            resultStr = putResult.getETag();
            map.put("resultStr", resultStr);
            map.put("guid", fileName);
            map.put("imageUrl", getUrl(fileName));
            System.out.println(map);
            // 关闭OSSClient。
            ossClient.shutdown();
        } catch (Exception e) {
            e.printStackTrace();
            log.error("上传阿里云OSS服务器异常." + e.getMessage(), e);
        }
        return map;
    }

    //上传返回url
    public String getFileUrl(File file) {
        //上传图片 file 文件 folder 文件夹名字
        OSSClient ossClient = AliyunOSSClientUtil.getOSSClient();
        Map map = uploadObject2OSS(ossClient, file, BACKET_NAME, FOLDER);
        return this.getUrl(map.get("imageUrl").toString());
    }

    public String getFileUrlNew(MultipartFile m, String bisType,String sessionKey) {
        OSSClient ossClient = AliyunOSSClientUtil.getOSSClient();
        Map map = this.uploadObject2OSSnew(ossClient, m, BACKET_NAME, FOLDER, bisType,sessionKey);
        return map.get("imageUrl").toString();
    }

    public Map<String, String> getFileUrlNewFlow(MultipartFile m, String bisType) {
        OSSClient ossClient = AliyunOSSClientUtil.getOSSClient();
        Map map = this.uploadObject2OSSnew(ossClient, m, BACKET_NAME, FOLDER, bisType,"");
        return map;
    }


}
AliyunOSSAutoConfigure上传下载方法
package com.central.file.config;

import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.central.file.model.FileInfo;
import com.central.file.properties.FileServerProperties;
import com.central.file.service.impl.AbstractIFileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.aliyun.oss.OSSClient;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

/**
 * 阿里云配置
 *
 * @author koko
 */
@Configuration
@ConditionalOnProperty(name = "cgs.file-server.type", havingValue = "aliyun")
public class AliyunOSSAutoConfigure {
    @Autowired
    private FileServerProperties fileProperties;

    /**
     * 阿里云文件存储client
     * 只有配置了aliyun.oss.access-key才可以使用
     */
    @Bean
    public OSSClient ossClient() {
        OSSClient ossClient = new OSSClient(fileProperties.getOss().getEndpoint()
                , new DefaultCredentialProvider(fileProperties.getOss().getAccessKey(), fileProperties.getOss().getAccessKeySecret())
                , null);
        return ossClient;
    }

    @Service
    public class AliyunOssServiceImpl extends AbstractIFileService {
        @Autowired
        private OSSClient ossClient;

        @Override
        protected String fileType() {
            return fileProperties.getType();
        }

        @Override
        protected void uploadFile(MultipartFile file, FileInfo fileInfo) throws Exception {
            ossClient.putObject(fileProperties.getOss().getBucketName(), fileInfo.getName(), file.getInputStream());
            fileInfo.setUrl(fileProperties.getOss().getDomain() + "/" + fileInfo.getName());
        }

        @Override
        protected boolean deleteFile(FileInfo fileInfo) {
            ossClient.deleteObject(fileProperties.getOss().getBucketName(), fileInfo.getName());
            return true;
        }
    }
}

阿里云上传接口访问(uploadImg)

package com.central.file.controller;

import com.central.common.model.PageResult;
import com.central.common.model.Result;
import com.central.common.utils.DateUtils;
import com.central.file.config.aliyun.AliyunOSSClientUtil;
import com.central.file.config.qiniu.UtilsUpload;
import com.central.file.model.FileInfo;
import com.central.file.model.ReturnMovo;
import com.central.file.service.IFileService;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 文件上传
 *
 * @author koko
 */
@Log4j2
@Controller
@RequestMapping("/aliyunFile")
@CrossOrigin
public class AliyunFileController {
    @Resource
    private IFileService fileService;
    @Autowired
    private Environment environment;
    /*@Resource
    private UserService userService;*/
    /**
     * 文件上传
     * 根据fileType选择上传方式
     *
     * @param file
     * @return
     * @throws Exception
     */
    @PostMapping("/files-anon")
    public FileInfo upload(@RequestParam("file") MultipartFile file) throws Exception {

        return fileService.upload(file);
    }

    /***
     * 阿里云上传图片
     */
    @RequestMapping("uploadImg")
    @ResponseBody
    public FileInfo uploadImg(@RequestParam MultipartFile file) {
        FileInfo resultModel = new FileInfo();
        Map<String, Object> map = new HashMap<>();
        try {
            if (!file.isEmpty()) {
                String avatar = new AliyunOSSClientUtil().getFileUrlNew(file, "", "");
                resultModel.setStatus(0);
                resultModel.setMsg("保存成功");
                resultModel.setPath(avatar);
                return resultModel;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }




//    /**
//     * 上传文件
//     */
//    @PostMapping("/updateFile")
//    @ResponseBody
//    public FileInfo updateFile(@RequestParam("file") MultipartFile file) {
//        FileInfo fileInfo = new FileInfo();
//
//        try {
//            if (!file.isEmpty()) {
//                String url = UtilsUpload.uploadImgByMultipartFile(file,false);
//                fileInfo.setUrl(url);
//            }
//        } catch (Exception e) {
//            fileInfo.setStatus(1);
//            fileInfo.setMsg("文件上传失败");
//        }
//        return fileInfo;
//    }

    /**
     * 上传文件
     */
    @PostMapping("/updateFile")
    @ResponseBody
    public FileInfo uploadFile(@RequestParam("file") MultipartFile file){
        FileInfo fileInfo = new FileInfo();
        // 判断文件是否为空
        String filePath = "";
        String filename = file.getOriginalFilename();
        //获取当前时间
        String timeStr = DateUtils.YMD.format(new Date());
        if (!file.isEmpty()) {
            try {
                //判断文件目录是否存在,否则自动生成
                File directory = new File(environment.getProperty("upload")+timeStr);
                    if (!directory.exists()){
                    directory.mkdir();
                }
                //失败跳转视图

                //获取图片扩展名
//                String ext = filename.substring(filename.lastIndexOf("."));
//                filename = StringUtils.gainGUID() +ext;
                // 文件保存路径
                filePath =  FilenameUtils.concat(environment.getProperty("upload")+timeStr, filename);
                // 转存文件
                file.transferTo(new File(filePath));

                fileInfo.setUrl(environment.getProperty("fileupload.directory")+timeStr+"/"+filename);
            } catch (Exception e) {
                e.printStackTrace();
                fileInfo.setStatus(1);
                fileInfo.setMsg("文件上传失败");
            }
        }
        //成功跳转视图
        return fileInfo;
    }

    @PostMapping("/updateFileEdit")
    @ResponseBody
    public ReturnMovo updateFileEdit(MultipartFile file) {
        ReturnMovo returnMovo = new ReturnMovo();
        Map<String, Object> map = new HashMap<>();
        try {
            if (!file.isEmpty()) {
                String url = UtilsUpload.uploadImgByMultipartFile(file,false);
                map.put("src", url);
                returnMovo.setData(map);
            }
        } catch (Exception e) {
            returnMovo.setCode(1);
            returnMovo.setMsg("文件上传失败");
        }
        return returnMovo;
    }

    /**
     * 文件删除
     *
     * @param id
     */
    @DeleteMapping("/files/{id}")
    public Result delete(@PathVariable String id) {
        try {
            fileService.delete(id);
            return Result.succeed("操作成功");
        } catch (Exception ex) {
            return Result.failed("操作失败");
        }
    }

    /**
     * 文件查询
     *
     * @param params
     * @return
     */
    @GetMapping("/files")
    public PageResult<FileInfo> findFiles(@RequestParam Map<String, Object> params) {
        return fileService.findList(params);
    }
}

前端就不写了,就是一种是单文件上传,另一种多文件上传。控件很多,有空再写。