锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

Java OOS 简单上传,分片上传(加进度条),(流式)下载文件

时间:2022-11-16 13:30:00 荧光法溶解氧传感器oos61

1.下载前端调用接口 (流式下载大文件可能比较慢!也可以直接下载URL的方式)

@GetMapping(value = "/downloadFile")     public void downloadFile(@RequestParam String ossPath, HttpServletResponse response) {         BufferedInputStream input;         OutputStream outputStream;         OSS ossClient = OssUtil.getOssBean();         try {             OSSObject ossObject = ossClient.getObject(OssUtil.BUCKET_NAME, ossPath); //            response.reset();             response.setCharacterEncoding("utf-8");             response.setContentType("application/x-msdownload");             response.addHeader("Content-Disposition",                     "attachment;fileName=\""   new String(ossPath.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8) "\""); //                    "attachment;filename=" new String(ossPath.getBytes("gb2312"), "ISO8859-1"));             input = new BufferedInputStream(ossObject.getObjectContent());             byte[] buffBytes = new byte[1024];             outputStream = response.getOutputStream();             int read;             while ((read = input.read(buffBytes)) != -1) {                 outputStream.write(buffBytes, 0, read);             }             outputStream.flush();             // 读取数据后,必须关闭获取的流量,否则会造成连接泄漏,导致要求无连接可用,程序无法正常工作。             ossObject.close();         } catch (OSSException | ClientException | IOException oe) {             oe.printStackTrace();         } finally {             if (ossClient != null) {                 ossClient.shutdown();             }         }     }

2.简单上传接口,官方可以上传进度条api实现,这块不做实现。

@PassToken     @ApiOperation("简单上传")     @PostMapping(value = "/uploadFile")     public RestResult saveFile(HttpServletRequest request) throws IOException {         ///获得上传文件夹的名称         String folderName = request.getParameter("folderName");         Map map = new HashMap<>();         MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;         MultipartFile multipartFile = multipartRequest.getFile("file");         // 获取文件名         assert multipartFile != null;         String fileName = multipartFile.getOriginalFilename();         // 获取文件后缀名         assert fileName != null;         String suffixName = fileName.substring(fileName.lastIndexOf("."));         // 最后上传生成的文件名         String substring = fileName.substring(0, fileName.lastIndexOf("."));         String previewName = substring   System.currentTimeMillis()   ""   new SecureRandom().nextInt(0x0400)   suffixName;         // oss中文件夹名         String ossPreviewName = folderName   "/"   previewName;         // 创建上传文件的元信息,可通过文件元信息设置HTTP header(通过返回链接设置直接访问)。         ObjectMetadata objectMetadata = new ObjectMetadata();         //设置文件类型         objectMetadata.setContentType(GetFileType.getContentType(suffixName));         Date expiration = new Date(System.currentTimeMillis()   3600L * 1000 * 24 * 365 * 50);         //文件预览         if ("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet".equals(objectMetadata.getContentType()) || "application/vnd.ms-powerpoint".equals(objectMetadata.getContentType()) || "application/msword".equals(objectMetadata.getContentType())) {             OssUtil.getOssBeanInner().putObject("你自己的bucketName", ossPreviewName, new ByteArrayInputStream(multipartFile.getBytes()), objectMetadata);             GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest("你自己的bucketName", ossPreviewName, HttpMethod.GET);             req.setExpiration(expiration);             req.setProcess(OssUtil.STYLE);             map.put("previewUrl", OssUtil.getOssBeanOut().generatePresignedUrl(req));         } else {             OssUtil.getOssBeanInner().putObject("你自己的bucketName", ossPreviewName, new ByteArrayInputStream(multipartFile.getBytes()), objectMetadata);             String previewUrl = OssUtil.getOssBeanOut().generatePresignedUrl("你自己的bucketName", ossPreviewName, expiration).toString();             map.put("previewUrl", previewUrl);         }         map.put("fileName", fileName);         map.put("ossPreviewName", ossPreviewName);         map.put("fileType", suffixName);         OssUtil.getOssBeanInner().shutdown();         OssUtil.getOssBeanOut().shutdown();         return RestResult.result(CommonResult.UPLOAD_SUCCESS, map);     } 
    

3.分片上传,官方分片上传不支持进度条,我用这个redis实现,也可用session

@PassToken     @PostMapping(value = "/multipartUpload")     public RestResult multipartUpload(HttpServletRequest request) throws Exception {         MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;         MultipartFile multipartFile = multipartRequest.getFile("file");         assert multipartFile != null;         String fileame = multipartFile.getOriginalFilename();
        assert fileName != null;
        String suffixName = fileName.substring(fileName.lastIndexOf("."));
        // 创建InitiateMultipartUploadRequest对象。
        InitiateMultipartUploadRequest iuRequest = new InitiateMultipartUploadRequest(OssUtil.BUCKET_NAME, "test/" + fileName);
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentType(GetFileType.getContentType(suffixName));
        //设置文件类型
        iuRequest.setObjectMetadata(objectMetadata);
        InitiateMultipartUploadResult upresult = OssUtil.getOssBeanInner().initiateMultipartUpload(iuRequest);
        // 返回uploadId,它是分片上传事件的唯一标识。您可以根据该uploadId发起相关的操作,例如取消分片上传、查询分片上传等。
        String uploadId = upresult.getUploadId();
        // partETags是PartETag的集合。PartETag由分片的ETag和分片号组成。
        List partETags = new ArrayList();
        // 每个分片的大小,用于计算文件有多少个分片。单位为字节。
        final long partSize = 10 * 1024 * 1024L;
        long fileLength = multipartFile.getSize();
        int partCount = (int) (fileLength / partSize);
        System.err.println(partCount);
        if (fileLength % partSize != 0) {
            partCount++;
        }
        // 遍历分片上传。
        for (int i = 0; i < partCount; i++) {
            long startPos = i * partSize;
            long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize;
            InputStream inputStream = multipartFile.getInputStream();
            // 跳过已经上传的分片。
            long skip = inputStream.skip(startPos);
            UploadPartRequest uploadPartRequest = new UploadPartRequest();
            uploadPartRequest.setBucketName(OssUtil.BUCKET_NAME);
            uploadPartRequest.setKey("test/" + fileName);
            uploadPartRequest.setUploadId(uploadId);
            uploadPartRequest.setInputStream(inputStream);
            // 设置分片大小。除了最后一个分片没有大小限制,其他的分片最小为100 KB。
            uploadPartRequest.setPartSize(curPartSize);
            // 设置分片号。每一个上传的分片都有一个分片号,取值范围是1~10000,如果超出此范围,OSS将返回InvalidArgument错误码。
            uploadPartRequest.setPartNumber(i + 1);

            // 每个分片不需要按顺序上传,甚至可以在不同客户端上传,OSS会按照分片号排序组成完整的文件。
            UploadPartResult uploadPartResult = OssUtil.getOssBeanInner().uploadPart(uploadPartRequest);
            // 每次上传分片之后,OSS的返回结果包含PartETag。PartETag将被保存在partETags中。
            partETags.add(uploadPartResult.getPartETag());

            BigDecimal div = BigDecimalUtil.div(i * 100, partCount);
            redisUtils.set("nowN", div.toString());
        }

        // 创建CompleteMultipartUploadRequest对象。
        // 在执行完成分片上传操作时,需要提供所有有效的partETags。OSS收到提交的partETags后,会逐一验证每个分片的有效性。当所有的数据分片验证通过后,OSS将把这些分片组合成一个完整的文件。
        CompleteMultipartUploadRequest completeMultipartUploadRequest =
                new CompleteMultipartUploadRequest(OssUtil.BUCKET_NAME, "test/" + fileName, uploadId, partETags);
        redisUtils.set("nowN", "100", 10000);
        // 完成分片上传。
        CompleteMultipartUploadResult completeMultipartUploadResult = OssUtil.getOssBeanInner().completeMultipartUpload(completeMultipartUploadRequest);
        String previewUrl = OssUtil.getOssBeanOut().generatePresignedUrl("你自己的bucketName","test/" + fileName , new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 50)).toString();
        final String location = completeMultipartUploadResult.getLocation();
        OssUtil.getOssBeanInner().shutdown();
        OssUtil.getOssBeanOut().shutdown();
        Map map = new HashMap<>();
        map.put("previewUrl",URLDecoder.decode(previewUrl,"UTF-8"));
        return RestResult.result(CommonResult.SUCCESS, map);
    } 
    

4,工具类Ossutil 

@Slf4j
public class OssUtil {
    public static final String STYLE = "imm/previewdoc,copy_1";
    /**
     * 查看自己的节点
     * (接口调用的话)内网上传 oss地址
     */
    public static final String INNER_ENDPOINT = "https://oss-cn-beijing-internal.aliyuncs.com";
    /**
     * 查看自己的节点
     * (接口调用的话)外网下载或预览 oss地址  oss-cn-beijing.aliyuncs.com
     */
    public static final String OUT_ENDPOINT = "https://oss-cn-beijing.aliyuncs.com";
    public static final String KEY_ID = "你自己的";
    public static final String KEY_SECRET = "你自己的";
    public static final String BUCKET_NAME = "你自己的";


    public static void delOssFile(String fileName) {
        if (fileName.isEmpty()){
            return;
        }
        OSS oss = new OSSClientBuilder().build(OUT_ENDPOINT, KEY_ID, KEY_SECRET);
        oss.deleteObject(BUCKET_NAME, fileName);
        oss.shutdown();
    }

    public static void delOssFile(String ossPreviewName,String ossDownloadName) {
        if (ossPreviewName.isEmpty()||ossDownloadName.isEmpty()){
            return;
        }
        OSS oss = new OSSClientBuilder().build(OUT_ENDPOINT, KEY_ID, KEY_SECRET);
        oss.deleteObject(BUCKET_NAME, ossPreviewName);
        oss.shutdown();
    }


    public static OSS getOssBeanInner(){
        return new OSSClientBuilder().build(INNER_ENDPOINT, KEY_ID, KEY_SECRET);
    }

    public static OSS getOssBeanOut(){
        return new OSSClientBuilder().build(OUT_ENDPOINT, KEY_ID, KEY_SECRET);
    }

    public static class PutObjectProgressListener implements ProgressListener {
        private HttpSession session;
        private long bytesWritten = 0;
        private long totalBytes = -1;
        private boolean succeed = false;
        private int percent = 0;

        //构造方法中加入session
        public PutObjectProgressListener() {
        }

        public PutObjectProgressListener(HttpSession mSession) {
            this.session = mSession;
            session.setAttribute("upload_percent", percent);
        }

        @Override
        public void progressChanged(ProgressEvent progressEvent) {
            long bytes = progressEvent.getBytes();
            ProgressEventType eventType = progressEvent.getEventType();
            switch (eventType) {
                case TRANSFER_STARTED_EVENT:
                    log.info("Start to upload......");
                    break;
                case REQUEST_CONTENT_LENGTH_EVENT:
                    this.totalBytes = bytes;
                    log.info(this.totalBytes + " bytes in total will be uploaded to OSS");
                    break;
                case REQUEST_BYTE_TRANSFER_EVENT:
                    this.bytesWritten += bytes;
                    if (this.totalBytes != -1) {
                        percent = (int) (this.bytesWritten * 100.0 / this.totalBytes);
                        //将进度percent放入session中
                        session.setAttribute("upload_percent", percent);
                        log.info(bytes + " bytes have been written at this time, upload progress: " + percent + "%(" + this.bytesWritten + "/" + this.totalBytes + ")");
                    } else {
                        log.info(bytes + " bytes have been written at this time, upload ratio: unknown" + "(" + this.bytesWritten + "/...)");
                    }
                    break;
                case TRANSFER_COMPLETED_EVENT:
                    this.succeed = true;
                    log.info("Succeed to upload, " + this.bytesWritten + " bytes have been transferred in total");
                    break;
                case TRANSFER_FAILED_EVENT:
                    log.info("Failed to upload, " + this.bytesWritten + " bytes have been transferred");
                    break;
                default:
                    break;
            }
        }

        public boolean isSucceed() {
            return succeed;
        }
    }

}

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章