文件上传至oss_阿里云存储对象OSS使用讲解二:java上传文件

bd4a3c8d958031d472961e57fa7cc11a.png

关于OSS的购买和配置,看这篇文章

https://blog.csdn.net/lianzhang861/article/details/82776197

我用的Spring mvc,maven项目,

1.首先引入包

         <dependency>            <groupId>com.aliyun.ossgroupId>            <artifactId>aliyun-sdk-ossartifactId>            <version>2.8.3version>        dependency>

2.创建OSSUtil

@Controllerpublic class OSSUtil {     @Value("${endpoint}")    private String endpoint;    @Value("${accessKeyId}")    private String accessKeyId;    @Value("${accessKeySecret}")    private String accessKeySecret;    @Value("${bucketName}")    private String bucketName;     //oss域名前缀,我绑定了CNAME所以用我的域名    private String key = "http://oss.zhulianzhang.com/";     /**     * 上传文件     *     * @param fileName 文件名     * @param inputStream 流     */    public String uploadFileToOss(String fileName, InputStream inputStream,String folder) {        /**         * 创建OSS客户端         */        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);        try {            String uuid = UUID.randomUUID().toString().replaceAll("-", "");            String[] names = fileName.split("[.]");            String name = uuid + "." + names[names.length - 1];            ossClient.putObject(new PutObjectRequest(bucketName, folder + name, inputStream));            return key + folder + name;        } catch (Exception e) {            e.printStackTrace();            System.err.println(e.getMessage());        } finally {            ossClient.shutdown();        }        return null;    }      /**     * 多文件上传     */    public String[] uploadFilesToOss(String[] fileNames, InputStream[] inputStreams,String folder) {        /**         * 创建OSS客户端         */        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);        try {            ConcurrentLinkedQueue concurrentLinkedQueue = new ConcurrentLinkedQueue(                    Arrays.asList(fileNames));            ConcurrentLinkedQueue streamConcurrentLinkedQueue = new ConcurrentLinkedQueue<>(                    Arrays.asList(inputStreams));            Iterator inputStreamss = streamConcurrentLinkedQueue.iterator();            ConcurrentLinkedQueue c = new ConcurrentLinkedQueue();            for (Iterator<String> iterator = concurrentLinkedQueue.iterator();                 iterator.hasNext() && inputStreamss.hasNext(); ) {                String uuid = UUID.randomUUID().toString().replaceAll("-", "");                String[] names = iterator.next().split("[.]");                String name = uuid + "." + names[names.length - 1];                ossClient.putObject(new PutObjectRequest(bucketName, folder + name, inputStreamss.next()));                c.add(key + folder + name);            }            return (String[]) c.toArray(new String[0]);        } catch (Exception e) {            e.printStackTrace();            System.err.println(e.getMessage());        } finally {            ossClient.shutdown();        }        return null;    }      /**     * 删除图片 警告:在没有调用其他方法的情况下,请调用closeClient方法     *     * @param url URL全路径     */    public void deleteImg(String url,String folder) {        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);        if (url == null || "".equals(url)) {            return;        }        String[] paths = url.split("[.]");        /**         * 文件夹是否存在         */        if (!ossClient.doesObjectExist(bucketName, folder)) {            ossClient.putObject(bucketName, folder, new ByteArrayInputStream(new byte[0]));        }        String[] name = paths[paths.length - 2].split("[/]");        /**         * 对象是否存在         */        if (ossClient                .doesObjectExist(bucketName,                        folder + name[name.length - 1] + "." + paths[paths.length - 1])) {            /**             * 删除存在对象             */            ossClient                    .deleteObject(bucketName, folder + name[name.length - 1] + "." + paths[paths.length - 1]);        }        ossClient.shutdown();    } }

配置信息我卸载config.properties调用的,调用方法可以看这篇文章有提到

https://blog.csdn.net/lianzhang861/article/details/82255867

注意:

@Value("${endpoint}")
private String endpoint;

这样调用配置的方法貌似只能在controller中使用,所以我在util类前面也加了@controller

config.properties中的配置:

d0f0f747a80ea6396f33f596fe7495b5.png

3.controller中使用

@Value("${imgFolder}")private String imgFolder;@Value("${videoFolder}")private String videoFolder;@Value("${coverFolder}")private String coverFolder;  // 上传文件到阿里云OSS@RequestMapping(value = "uploadFileToOss", method = RequestMethod.POST, produces = "application/json;charset=utf-8")@ResponseBodypublic void uploadFileToOss(        @RequestParam Mapparams,        @RequestParam(value = "file") MultipartFile[] files,        HttpServletRequest request){    String folder="";    //判断文件类型分配不同文件夹下    if(params.get("attachmentType").equals("IMAGE")){        folder=imgFolder;    }else if(params.get("attachmentType").equals("VIDEO")){        folder=videoFolder;    }     int userId=((TSystemUser)request.getSession().getAttribute("USER")).getUserId();    params.put("userId",userId);    //缩略图,不是视频则保存空    params.put("attachmentThumbnail","");    try {        //因为springmvc注解访问了inputstream封装成了MultipartFile,而inputstream只能被碰一次,所以得把MultipartFile        //在转换成inputstream格式,因为oss上传只接受inputstream格式        for (MultipartFile file : files) {    //将MultipartFile转换成inputStream            String fileName = file.getOriginalFilename();            CommonsMultipartFile cFile = (CommonsMultipartFile) file;            DiskFileItem fileItem = (DiskFileItem) cFile.getFileItem();            InputStream inputStream = fileItem.getInputStream();            InputStream stream1;            InputStream stream2;            if(params.get("attachmentType").equals("VIDEO")){                //因为inputStream只能读取一次,所以要复制出来一份                ByteArrayOutputStream baosOutputStream = new ByteArrayOutputStream();                byte[] buffer = new byte[1024];                int len;                while ((len = inputStream.read(buffer)) > -1) {                    baosOutputStream.write(buffer, 0, len);                }                baosOutputStream.flush();                 stream1 = new ByteArrayInputStream(baosOutputStream.toByteArray());                stream2 = new ByteArrayInputStream(baosOutputStream.toByteArray());                baosOutputStream.close();             }else{                stream1=inputStream;                stream2=inputStream;            }            //上传文件到oss返回路径            String fileUrl= ossUtil.uploadFileToOss(fileName,stream1,folder);            params.put("attachmentUrl",fileUrl);            params.put("attachmentName",fileName);            //如果是视频类型,则保存封面            if(params.get("attachmentType").equals("VIDEO")){                //用javacv进行视频截取帧                FFmpegFrameGrabber ff = new FFmpegFrameGrabber(stream2);                ff.start();                int length = ff.getLengthInFrames();                int i = 0;                Frame f = null;                while (i < length) {                    // 过滤前5帧,避免出现全黑的图片,依自己情况而定                    f = ff.grabImage();                    if ((i > 5) && (f.image != null)) {                        break;                    }                    i++;                }                //为了将图片上传OSS,将其转换成inputStream格式                InputStream cover=FrameToBufferedImage(f);                //上传视频封面到oss返回路径                String coverUrl= ossUtil.uploadFileToOss("cover.jpg",cover,coverFolder);                params.put("attachmentThumbnail",coverUrl);            }            inputStream.close();            stream1.close();            stream2.close();            attachmentService.saveFile(params);        }    } catch (Exception e) {        e.printStackTrace();    }} //把Frame转换成inputStream类型public static InputStream FrameToBufferedImage(Frame frame) throws IOException {    //创建BufferedImage对象    Java2DFrameConverter converter = new Java2DFrameConverter();    BufferedImage bufferedImage = converter.getBufferedImage(frame);     ByteArrayOutputStream os = new ByteArrayOutputStream();    ImageIO.write(bufferedImage, "jpg", os);    InputStream is = new ByteArrayInputStream(os.toByteArray());     return is;}

我写的是文件上传的通用接口,其中包括视频上传后截取视频封面,所以比较复杂,

关于视频截取封面,参考这个https://blog.csdn.net/lianzhang861/article/details/82014460

坑:

1.oss上传需要传入文件流inputStream或者file类型,而spring mvc接收前台form表单传输的文件流会访问inputstream,转为MultipartFile格式,inputstream只能访问一次,所以在spring mvc中直接获取inputstream会报空,所以需要将multipart格式转化成inputstream

2.转化后的inputstream也只能用一次,而我上传视频时需要先上传文件,在上传截取的封面,需要使用两次inputstream,所以必须复制出来一份inputstream,代码中有写到

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值