OSS文件上传

部署运行你感兴趣的模型镜像

1、我们这个系统对接的阿里云OSS需要先对接小鹏OSS系统获取accessKeyId、accessKeySecret,这个可以忽略

aliyun:
  oss:
    endpoint: https://oss-cn-hangzhou.aliyuncs.com
    bucketName: xp-xpd-experience
    domain: https://xp-xpd-experience.oss-cn-hangzhou.aliyuncs.com
    # 目录权限,不能瞎写,msedprod   msedtest
    folder: msedtest
    # 上传文件大小
    maxSizeStr: 3000
    # redis过期时间(单位:分钟)
    timeoutKey: 1
    ossRedisKey: oss:file:key
  auth:
    idTokenUrl: https://ldap.test.xiaopeng.com/oidc/token
    clientId: xp-msed-api-boot
    clientSecret: ecDLIIhReieMYgvHQ
    grant_type: client_credentials
    stsAccessKeyUrl: http://apisix-gw-ali-hd1.test.xiaopeng.com/voyager-authhub/api/sts/get_token
    policeName: XpMsedApiBootTESTOss

2、接口

@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @Operation(summary = "单文件上传")
    public Result<SysFileRecordVO> uploadFile(@RequestPart MultipartFile file, @RequestParam(value = "folderName", defaultValue = "", required = false) String folderName,
                                              @RequestParam(defaultValue = "OTHER", required = false) FileTypeEnum fileType) {
        return R.successWithData(sysFileRecordService.upload(file, folderName, fileType), "文件上传成功!");
    }

@GetMapping(value = "/previewFile")
    @Operation(summary = "OSS文件预览")
    public Result<String> previewFile(@RequestParam(value = "fileName") String fileName) {
        String url = sysFileRecordService.getUrl(fileName);
        return R.successWithData(url);
    }

    @PostMapping(value = "/uploads", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @Operation(summary = "多文件上传")
    Result<List<SysFileRecordVO>> uploadFile(@RequestPart MultipartFile[] files, @RequestParam(defaultValue = "OTHER", required = false) FileTypeEnum fileType) {
        return R.successWithData(sysFileRecordService.uploads(files, fileType), "文件上传成功!");
    }

@GetMapping(value = "/downloadById/{id}")
    @Operation(summary = "根据id下载文件")
    @Parameters({@Parameter(description = "id", in = ParameterIn.PATH, name = "id"), @Parameter(description = "名称", name = "name")})
    ResponseEntity<byte[]> downloadById(@PathVariable Integer id, String name) {
        return sysFileRecordService.downloadById(id, name);
    }

@Operation(summary = "文件预览")
    @GetMapping(value = "/filePreview/{path}")
    @Parameter(description = "文件路径", name = "path", in = ParameterIn.PATH)
    public ResponseEntity<byte[]> filePreview(@PathVariable("path") String path) {
        return sysFileRecordService.filePreview(path);
    }

service层

@Slf4j
@Primary
@Service(value = "sysOssFileRecordServiceImpl")
@ConditionalOnProperty(name = "oss.env.oss", havingValue = "true", matchIfMissing = true)
public class SysOssFileRecordServiceImpl extends ServiceImpl<SysFileRecordMapper, SysFileRecord> implements SysFileRecordService {

    @Autowired
    private OssConfig ossConfig;

    @Autowired
    private OssAuthConfig ossAuthConfig;

    @Autowired
    private CacheService cacheService;

@Override
    @Transactional(rollbackFor = Exception.class)
    public SysFileRecordVO upload(MultipartFile file, String folderName, FileTypeEnum fileTypeEnum) {

        String ossRedisKey = ossConfig.getOssRedisKey();
        String securityToken = (String) cacheService.hGet(ossRedisKey, "securityToken");
        String accessKeyIdKey = (String) cacheService.hGet(ossRedisKey, "accessKeyId");
        String accessKeySecretKey = (String) cacheService.hGet(ossRedisKey, "accessKeySecret");
        if (StringUtils.isBlank(accessKeyIdKey) && StringUtils.isBlank(accessKeySecretKey)) {
            Map<String, String> map = getAccessKeyIdSecret();
            accessKeyIdKey = map.get("accessKeyId");
            accessKeySecretKey = map.get("accessKeySecret");
            securityToken = map.get("securityToken");
        }

        // Map<String, String> map = getAccessKeyIdSecret();
        // String accessKeyIdKey = map.get("accessKeyId");
        // String accessKeySecretKey = map.get("accessKeySecret");
        // String securityToken = map.get("securityToken");

        log.info("accessKeyIdKey:{}", accessKeyIdKey);
        log.info("accessKeySecretKey:{}", accessKeySecretKey);
        log.info("securityToken:{}", securityToken);
        log.info("file:{}", file);

        if (file == null) {
            throw new ServiceException("文件不能为空");
        }

        String originalFilename = file.getOriginalFilename();
        if (StringUtils.isEmpty(originalFilename)) {
            throw new ServiceException("文件不能为空");
        }
        log.info("originalFilename:{}", originalFilename);

        // 默认限制2M
        float maxSize = 2;
        try {
            maxSize = Float.parseFloat(ossConfig.getMaxSizeStr());
        } catch (NumberFormatException e) {
            log.error("图片允许的大小设置不正确", e);
            throw new ServiceException("图片允许的大小设置不正确");
        }
        if (file.getSize() > (maxSize * 1024 * 1024)) {
            throw new ServiceException("上传的文件不能大于" + maxSize + "MB");
        }

        // 保存文件
        try {
            String fileName = saveFile(file, folderName);

            // 上传阿里云oss
            String endpoint = ossConfig.getEndpoint();
            String bucketName = ossConfig.getBucketName();
            String folder = ossConfig.getFolder();
            log.info("bucketName:{}", bucketName);
            log.info("endpoint:{}", endpoint);
            log.info("folder:{}", folder);

            OSS ossClient = AliyunOssUtil.getOSSClient(accessKeyIdKey, accessKeySecretKey, endpoint, securityToken);
            File ossFile = new File(fileName);
            Map<String, String> upload = AliyunOssUtil.upload(ossClient, ossFile, bucketName, folder, folderName);
            log.info("upload:{}", upload);
            fileName = upload.get("resultStr");
            AssertUtil.isNotBlank(fileName, "小鹏OSS上传失败");
            /*if (StringUtils.isBlank(fileName)) {
                throw new ServiceException("小鹏OSS上传失败");
            }*/
            log.info("fileName:{}", fileName);
            String fileNameEncode = Base64.encode(fileName);
            SysFileRecordVO sysFileRecordVO = new SysFileRecordVO();
            sysFileRecordVO.setFilePath(fileNameEncode);
            sysFileRecordVO.setFileName(originalFilename);
            return sysFileRecordVO;
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException("上传失败");
        }
    }

       @Override
    public ResponseEntity<byte[]> downloadFile(String path, String name, boolean isPreview) {
        String ossRedisKey = ossConfig.getOssRedisKey();
        path = Base64.decodeStr(path);
        String securityToken = (String) cacheService.hGet(ossRedisKey, "securityToken");
        String accessKeyIdKey = (String) cacheService.hGet(ossRedisKey, "accessKeyId");
        String accessKeySecretKey = (String) cacheService.hGet(ossRedisKey, "accessKeySecret");
        if (StringUtils.isBlank(accessKeyIdKey) && StringUtils.isBlank(accessKeySecretKey)) {
            Map<String, String> map = getAccessKeyIdSecret();
            accessKeyIdKey = map.get("accessKeyId");
            accessKeySecretKey = map.get("accessKeySecret");
            securityToken = map.get("securityToken");
        }

        String endpoint = ossConfig.getEndpoint();
        String bucketName = ossConfig.getBucketName();
        OSSClient ossClient = new OSSClient(endpoint, accessKeyIdKey, accessKeySecretKey, securityToken);
        OSSObject ossObject = ossClient.getObject(bucketName, path);

        try {
            boolean found = ossClient.doesObjectExist(bucketName, path); // 检查文件是否存在
            if (found) {
                InputStream inputStream = ossObject.getObjectContent();
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                byte[] readBuffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = inputStream.read(readBuffer)) != -1) {
                    byteArrayOutputStream.write(readBuffer, 0, bytesRead);
                }
                byte[] fileBytes = byteArrayOutputStream.toByteArray();

                // 根据isPreview标志来设置响应头
                HttpHeaders headers = new HttpHeaders();
                if (isPreview) {
                    // 预览模式,根据文件扩展名设置合适的Content-Type
                    String contentType = getContentTypeByFileName(path);
                    headers.setContentType(MediaType.parseMediaType(contentType));
                } else {
                    // 下载模式,设置Content-Disposition为附件
                    // 对文件名进行URL编码,并指定编码方式
                    if (StringUtils.isBlank(name)) {
                        int i = path.lastIndexOf("/");
                        path = path.substring(i + 1);
                    } else {
                        path = name;
                    }
                    String encodedFileName = URLEncoder.encode(path, "UTF-8").replaceAll("\\+", "%20");
                    headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + encodedFileName);
                    // headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"");
                    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
                }

                // 关闭输入流和输出流
                inputStream.close();
                byteArrayOutputStream.close();

                return new ResponseEntity<>(fileBytes, headers, HttpStatus.OK);
            }
            return ResponseEntity.notFound().build();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            ossClient.shutdown();
        }
    }

    // 根据文件名获取文件的MIME类型
    private String getContentTypeByFileName(String fileName) {
        String lowerCaseName = fileName.toLowerCase();
        if (lowerCaseName.endsWith(".pdf")) {
            return MediaType.APPLICATION_PDF_VALUE;
        } else if (lowerCaseName.endsWith(".jpg") || lowerCaseName.endsWith(".jpeg")) {
            return MediaType.IMAGE_JPEG_VALUE;
        } else if (lowerCaseName.endsWith(".png")) {
            return MediaType.IMAGE_PNG_VALUE;
        } else if (lowerCaseName.endsWith(".gif")) {
            return MediaType.IMAGE_GIF_VALUE;
        } else if (lowerCaseName.endsWith(".ppt")) {
            return "application/vnd.openxmlformats-officedocument.presentationml.presentation";
        } else if (lowerCaseName.endsWith(".xlsx") || lowerCaseName.endsWith(".xls")) {
            return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        } else if (lowerCaseName.endsWith(".docx") || lowerCaseName.endsWith(".doc")) {
            return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
        } else {
            // 如果文件类型未知,则使用默认的二进制类型
            return MediaType.APPLICATION_OCTET_STREAM_VALUE;
        }
    }

   /**
     * 获取文件临时访问路径
     *
     * @param fileName 文件名
     * @return YouTube:乌鲁木齐中路纪录片
     */
    @Override
    public String getUrl(String fileName) {
        String ossRedisKey = ossConfig.getOssRedisKey();
        String accessKeyIdKey = (String) cacheService.hGet(ossRedisKey, "accessKeyId");
        String accessKeySecretKey = (String) cacheService.hGet(ossRedisKey, "accessKeySecret");
        String securityToken = (String) cacheService.hGet(ossRedisKey, "securityToken");
        if (StringUtils.isBlank(accessKeyIdKey) && StringUtils.isBlank(accessKeySecretKey)) {
            Map<String, String> map = getAccessKeyIdSecret();
            accessKeyIdKey = map.get("accessKeyId");
            accessKeySecretKey = map.get("accessKeySecret");
            securityToken = map.get("securityToken");
        }
        String endpoint = ossConfig.getEndpoint();
        String bucketName = ossConfig.getBucketName();
        OSSClient ossClient = new OSSClient(endpoint, accessKeyIdKey, accessKeySecretKey, securityToken);
        // 设置URL过期时间为1小时
        Date expiration = new Date(new Date().getTime() + 3600 * 1000);
        GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, fileName);
        generatePresignedUrlRequest.setExpiration(expiration);
        URL url = ossClient.generatePresignedUrl(generatePresignedUrlRequest);
        return url.toString();
    }

    public String saveFile(MultipartFile file, String folderName) throws Exception {
        String fileName = file.getOriginalFilename();
        String imageName = fileName.substring(fileName.lastIndexOf("."));

        // String pathRoot = ossConfig.getPathRoot();
        // String baseImage = ossConfig.getBaseImage();
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");

        // if (pathRoot == null || StringUtils.isEmpty(pathRoot)) {
        //     pathRoot = ResourceUtils.getURL("classpath:").getPath();
        // }

        String filePath = DateUtil.formatDate(new Date(), "yyyyMMdd") + "/";

        String path = filePath + uuid + imageName;
        if (StringUtils.isNotBlank(folderName)) {
            path = filePath + fileName;
        }

        try {
            File tempFile = new File(path);
            if (!tempFile.getParentFile().exists()) {
                tempFile.getParentFile().mkdirs();
            }
            CommonUtil.saveMultipartFile(file, path);
        } catch (Exception e) {
            throw new Exception("上传失败,请检查目录是否可写");
        }

        return path;
    }

    public Map<String, String> getAccessKeyIdSecret() {
        String clientId = ossAuthConfig.getClientId();
        log.info("clientId:{}", clientId);
        String clientSecret = ossAuthConfig.getClientSecret();
        log.info("clientSecret:{}", clientSecret);
        String idTokenUrl = ossAuthConfig.getIdTokenUrl();
        log.info("idTokenUrl:{}", idTokenUrl);
        String obj = OSSAccessKeyUtils.getIdToken(clientId, clientSecret, idTokenUrl);
        log.info("obj:{}", obj);
        if (StringUtils.isBlank(obj)) {
            throw new ServiceException("获取ID Token失败");
        }
        JSONObject jsonObject = new JSONObject(obj);
        String idToken = (String) jsonObject.get("id_token");
        log.info("idToken:{}", idToken);

        String stsAccessKeyUrl = ossAuthConfig.getStsAccessKeyUrl();
        log.info("stsAccessKeyUrl:{}", stsAccessKeyUrl);
        String policeName = ossAuthConfig.getPoliceName();
        log.info("policeName:{}", policeName);

        Long timeoutKey = ossConfig.getTimeoutKey();
        log.info("timeoutKey:{}", timeoutKey);
        JSONObject stsObj = OSSAccessKeyUtils.getStsToken(idToken, policeName, stsAccessKeyUrl);
        log.info("stsObj:{}", stsObj);
        if (stsObj == null) {
            throw new ServiceException("获取STS Token失败");
        }
        JSONObject dataObj = (JSONObject) stsObj.get("data");
        String accessKeyId = (String) dataObj.get("AccessKeyId");
        String accessKeySecret = (String) dataObj.get("AccessKeySecret");
        String expiration = (String) dataObj.get("Expiration");
        String securityToken = (String) dataObj.get("SecurityToken");

        log.info("accessKeyId:{}", accessKeyId);
        log.info("accessKeySecret:{}", accessKeySecret);
        log.info("expiration:{}", expiration);
        log.info("securityToken:{}", securityToken);

        String ossRedisKey = ossConfig.getOssRedisKey();

        cacheService.hPut(ossRedisKey, "accessKeyId", accessKeyId);
        cacheService.hPut(ossRedisKey, "accessKeySecret", accessKeySecret);
        cacheService.hPut(ossRedisKey, "expiration", expiration);
        cacheService.hPut(ossRedisKey, "securityToken", securityToken);
        cacheService.expire(ossRedisKey, timeoutKey == null ? 2 : timeoutKey, TimeUnit.MINUTES);

        Map<String, String> result = Maps.newHashMap();
        result.put("accessKeyId", accessKeyId);
        result.put("accessKeySecret", accessKeySecret);
        result.put("securityToken", securityToken);
        log.info("result:{}", result);
        return result;
    }

}

需要的工具类

package com.ruiyada.common.core.utils;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.Bucket;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.PutObjectResult;
import com.aliyun.oss.model.VoidResult;
import com.aliyuncs.exceptions.ClientException;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;

/**
 * 阿里云OSS存储工具
 *
 * Created by FSQ
 * CopyRight https://www.fuint.cn
 */
@Slf4j
public class AliyunOssUtil {

    private static final Logger logger = LoggerFactory.getLogger(AliyunOssUtil.class);

    /**
     * 获取阿里云OSS客户端对象
     *
     * @param accessKeyId 访问键值
     * @param accessKeySecret 访问秘钥
     * @param endpoint 存储endPoint
     * @return ossClient
     */
    public static OSS getOSSClient(String accessKeyId, String accessKeySecret, String endpoint) {
        return new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    }

    public static OSS getOSSClient(String accessKeyId, String accessKeySecret, String endpoint, String securityToken) throws ClientException {
        return new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret, securityToken);
    }

    /**
     * 创建存储空间
     *
     * @param ossClient OSS连接
     * @param bucketName 存储空间
     * @return
     */
    public static String createBucketName(OSS ossClient, String bucketName) {
        // 存储空间
        final String bucketNames = bucketName;

        if (!ossClient.doesBucketExist(bucketName)) {
            // 创建存储空间
            Bucket bucket = ossClient.createBucket(bucketName);
            logger.info("创建存储空间成功");
            return bucket.getName();
        }

        return bucketNames;
    }

    /**
     * 创建模拟文件夹
     *
     * @param ossClient oss连接
     * @param bucketName 存储bucket
     * @param folder 文件夹
     * @return 文件夹名
     */
    public static String createFolder(OSS ossClient, String bucketName, String folder) {
        // 文件夹名
        final String keySuffixWithSlash = folder;

        // 判断文件夹是否存在,不存在则创建
        if (!ossClient.doesObjectExist(bucketName, keySuffixWithSlash)) {
            // 创建文件夹
            ossClient.putObject(bucketName, keySuffixWithSlash, new ByteArrayInputStream(new byte[0]));
            logger.info("创建文件夹成功");
            // 得到文件夹名
            OSSObject object = ossClient.getObject(bucketName, keySuffixWithSlash);
            String fileDir = object.getKey();
            return fileDir;
        }

        return keySuffixWithSlash;
    }

    /**
     * 上传图片至OSS
     *
     * @param ossClient oss连接
     * @param file 上传文件(文件全路径如:D:\\image\\cake.jpg)
     * @return String 返回文件url
     */
    public static Map<String, String> upload(OSS ossClient, File file, String bucketName, String folder, String folderName) {
        String resultStr = null;

        // 先创建存储空间和文件夹
        // createBucketName(ossClient, bucketName);
        // createFolder(ossClient, bucketName, folder);
        Map<String, String> resultMap = Maps.newHashMap();
        try {
            InputStream is = new FileInputStream(file);
            String fileName = file.getName();
            // String date = DateUtil.formatDate(new Date(), "yyyyMMdd");
            String date = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
            String path = "";
            if (StringUtils.isNotBlank(folderName)) {
                path = folder + "/" + folderName + "/" + date + "/" + fileName;
            } else {
                path = folder + "/" + date + "/" + fileName;
            }
            PutObjectResult putObjectResult = ossClient.putObject(bucketName, path, is);
            String versionId = putObjectResult.getVersionId();
            String requestId = putObjectResult.getRequestId();
            if (StringUtils.isNotBlank(folderName)) {
                resultStr = folder + "/" + folderName + "/" + date + "/" + fileName;
            } else {
                resultStr = folder + "/" + date + "/" + fileName;
            }
            resultMap.put("versionId", versionId);
            resultMap.put("requestId", requestId);
            resultMap.put("resultStr", resultStr);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("上传阿里云OSS服务器异常." + e.getMessage(), e);
        }

        return resultMap;
    }

    /**
     * 根据key删除OSS上的文件
     *
     * @param ossClient oss连接
     * @param key Bucket下的文件的路径名+文件名 如:"upload/cake.jpg"
     */
    public static void deleteFile(OSS ossClient, String bucketName, String folder, String key) {
        boolean found = ossClient.doesObjectExist(bucketName, key); // 这行判断为true,说明文件存在
        if (found) {
            // ossClient.deleteObject(bucketName, folder + key);
            VoidResult voidResult = ossClient.deleteObject(bucketName, key);
            log.info("删除文件返回结果:" + voidResult);
        }

        logger.info("删除" + bucketName + "下的文件" + folder + key + "成功");
    }

    public static Map<String, String> uploadInputStream(OSS ossClient, File file, String bucketName, String folder, String folderName) {
        String resultStr = null;

        // 先创建存储空间和文件夹
        Map<String, String> resultMap = Maps.newHashMap();
        try {
            InputStream is = new FileInputStream(file);
            String fileName = file.getName();
            // String date = DateUtil.formatDate(new Date(), "yyyyMMdd");
            String date = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
            String path = "";
            if (StringUtils.isNotBlank(folderName)) {
                path = folder + "/" + folderName + "/" + date + "/" + fileName;
            } else {
                path = folder + "/" + date + "/" + fileName;
            }
            PutObjectResult putObjectResult = ossClient.putObject(bucketName, path, is);
            String versionId = putObjectResult.getVersionId();
            String requestId = putObjectResult.getRequestId();
            if (StringUtils.isNotBlank(folderName)) {
                resultStr = folder + "/" + folderName + "/" + date + "/" + fileName;
            } else {
                resultStr = folder + "/" + date + "/" + fileName;
            }
            resultMap.put("versionId", versionId);
            resultMap.put("requestId", requestId);
            resultMap.put("resultStr", resultStr);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("上传阿里云OSS服务器异常." + e.getMessage(), e);
        }

        return resultMap;
    }

}

您可能感兴趣的与本文相关的镜像

GPT-oss:20b

GPT-oss:20b

图文对话
Gpt-oss

GPT OSS 是OpenAI 推出的重量级开放模型,面向强推理、智能体任务以及多样化开发场景

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值