关于阿里云OSS上传以及下载的处理方法

正好这个项目快结束了 ,被阿里云下载折腾了好久,网上相关支持又比较少,所有我结合自己的项目,简单的讲一下。
1.OSSObjectUtils基于OSS官方文档写的工具类  
public class OSSObjectUtils {

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

    private static OSSClient ossClient = new OSSClient(OSSConfig.ENDPOINT_SHANGHAI, OSSConfig.ACCESSKEY_ID, OSSConfig.ACCESSKEY_SECRET);
    //private static OSSClient ossClient = new OSSClient("http://oss-cn-shanghai.aliyuncs.com", "0aHuVNGwxXsHDRIg", "6dvOMka7ON0DogefcWm09MbR4ofymB");

    private static String ENDPOINTINFO = ossClient.getEndpoint().toString();

    private OSSObjectUtils() {

    }

    /**
     * 创建Bucket
     * 
     * @param bucketName
     * @throws OSSException
     * @throws ClientException
     */
    @SuppressWarnings("unused")
    @Deprecated
    private static void createBucket(String bucketName) throws OSSException, ClientException {
        if (!ossClient.doesBucketExist(bucketName)) {
            logger.info(ENDPOINTINFO + "创建bucketName:" + bucketName);
            ossClient.createBucket(bucketName);
        }
    }

    public static boolean isExistObject(String bucketName, String key) {
        boolean result = false;
        try {
            result = ossClient.doesObjectExist(bucketName, key);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 上传object
     * 
     * @param bucketName
     * @param key
     * @param inputStream
     * @throws OSSException
     * @throws ClientException
     */
    public static void putObject(String bucketName, String key, InputStream inputStream)
            throws OSSException, ClientException {
        logger.info(ENDPOINTINFO + "上传Object,bucketName=" + bucketName + ",key=" + key);
        ossClient.putObject(bucketName, key, inputStream);
    }

    /**
     * 上传object
     * 
     * @param bucketName
     * @param key
     * @param inputStream
     * @throws OSSException
     * @throws ClientException
     */
    public static void putObject(String bucketName, String key, File file) throws OSSException, ClientException {
        logger.info(ENDPOINTINFO + "上传Object,bucketName=" + bucketName + ",key=" + key);
        ossClient.putObject(bucketName, key, file);
    }

    /**
     * 上传object,带元数据
     * 
     * @param bucketName
     * @param key
     * @param inputStream
     * @param meta
     * @throws OSSException
     * @throws ClientException
     */
    public static void putObject(String bucketName, String key, InputStream inputStream, ObjectMetadata meta)
            throws OSSException, ClientException {
        logger.info(ENDPOINTINFO + "上传Object,bucketName=" + bucketName + ",key=" + key);
        ossClient.putObject(bucketName, key, inputStream, meta);
    }

    /**
     * 上传object,带进度listener
     * 
     * @param bucketName
     * @param key
     * @param inputStream
     * @param listener
     * @throws Exception
     */
    public static void putObject(String bucketName, String key, InputStream inputStream,
            PutObjectProgressListener listener) throws Exception {
        logger.info(ENDPOINTINFO + "上传Object,带进度监听,bucketName=" + bucketName + ",key=" + key);
        ossClient.putObject(
                new PutObjectRequest(bucketName, key, inputStream).<PutObjectRequest> withProgressListener(listener));
    }

    /**
     * 签名url
     *
     * @author kira
     * @param bucketName
     * @param key
     * @param expiration
     *            有效期
     * @return
     */
    public static URL generatePresignedUrl(String bucketName, String key, Date expiration) {
        logger.info(ENDPOINTINFO + "获取URL,bucketName=" + bucketName + ",key=" + key);
        return ossClient.generatePresignedUrl(bucketName, key, expiration);
    }

    /**
     * 获取object,并读取流输出至OutputStream<br>
     * 用于流式下载
     *
     * @author kira
     * @param bucketName
     * @param key
     * @param out
     * @throws IOException
     */
    public static void getObjectToOutputStream(String bucketName, String key, OutputStream out) throws IOException {
        logger.info(ENDPOINTINFO + "获取Object,输出至OutputStream,bucketName=" + bucketName + ",key=" + key);
        byte[] buf = new byte[1024];
        InputStream in = ossClient.getObject(bucketName, key).getObjectContent();
        int length = 0;
        while ((length = in.read(buf)) > 0) {
            out.write(buf, 0, length);
        }

        in.close();
        out.close();
    }

    /**
     * 获取Object的Byte<br>
     * 由于读取整个object至内存,故大文件不建议使用此方法,容易内存溢出
     * 
     * @author kira
     * @param bucketName
     * @param key
     * @return
     * @throws IOException
     */
    public static byte[] getObjectByte(String bucketName, String key) throws IOException {
        logger.info(ENDPOINTINFO + "获取Object的Byte,bucketName=" + bucketName + ",key=" + key);
        byte[] buf = new byte[1024];
        InputStream in = ossClient.getObject(bucketName, key).getObjectContent();
        for (int n = 0; n != -1;) {
            n = in.read(buf, 0, buf.length);
        }
        in.close();
        return buf;
    }

    public static void main(String[] args){
        /*List<Bucket> list= ossClient.listBuckets();
        for(Bucket b:list){
            System.out.println(b.getName());
        }*/
        //file/policyfile/236e7e90-0d9c-4fa7-b7f3-ffededb3f8d8.png
        List<OSSObjectSummary> list=ossClient.listObjects("xsjyappstatic","file/policyfile/").getObjectSummaries();
        for(OSSObjectSummary ossos:list){
            System.out.println("##############################");
            System.out.println(ossos.getKey());
            //ossClient.deleteObject("jyjyimage", ossos.getKey());
        }
        //System.out.println(DateUtils.sdf_yMdHmsS.format(new Date()));
        //System.out.println(ossClient.doesObjectExist("jyjyimage", "schoolbase-video/20170408134128185_WI4QUI105.mps4"));
    }

}

工具类准备好后 我们着手写自己上传controller,基于项目代码,我们简单的看一下。
为了精简 删除了一下与上传无关的代码
2.上传controller

@ResponseBody
    @RequestMapping("/upload")
    public String Upload(HttpServletRequest request,
            @RequestParam("uploadfile") MultipartFile uploadfile,
            @RequestParam("comm") String comm,
            @RequestParam("csrftoken") String csrftoken){
    String csrftoken_serssion = (String)request.getSession().getAttribute(com.unisolution.xsjy.jyj.helpers.SessionKeys.CSRFTOKEN);

        Users sessionuser = SessionHelperForLogin.getSessionUser(request.getSession());

        Map<String, Object> returnmap = new HashMap<String, Object>();
        returnmap.put("status", "0");
        returnmap.put("msg", "文件上传失败");

        if(dgradeTypes!=null&&dgradeTypes.length>0 && uploadfile!=null && StringUtils.equals(csrftoken_serssion, csrftoken)){

            String key=OSSConfig.OBJECTKEY_PREFIX_FILE_POLICYFILE+UUID.randomUUID().toString()+"."+StringUtils.substringAfterLast(uploadfile.getOriginalFilename(), ".");
            try {
                //application/octet-stream
                //ObjectMetadata meta=new ObjectMetadata();
                //meta.setContentType("application/octet-stream");
                OSSObjectUtils.putObject(OSSConfig.BUCKETNAME_XSJY_STATICSERVER, key, uploadfile.getInputStream());

                PolicyFile policyFile=new PolicyFile();

                policyFile.setFileNameOriginal(uploadfile.getOriginalFilename());

                /*
                 *  FILE_SIZE 
                    FILE_PATH //阿里云地址
                    FILE_PATH_CUSTOMDOMAIN //域名地址
                    FILE_PATH_RELATIVE//域名后缀的详细地址
                    www.ys.com/xsjy(bucketName)/file(key前缀)/asd51d1a.doc(uuid命名的)
                 */
                String file_path =OSSConfig.ENDPOINT_SHANGHAI+"/"+OSSConfig.BUCKETNAME_XSJY_STATICSERVER+"/"+key;
                String file_path_customdomain =OSSConfig.CUSTOMDOMAIN_XSJY_STATICSERVER+"/"+key;
                String file_path_relative="/"+OSSConfig.BUCKETNAME_XSJY_STATICSERVER+"/"+key;

                policyFile.setFilePath(file_path);
                policyFile.setFilePathCustomdomain(file_path_customdomain);
                policyFile.setFilePathRelative(file_path_relative);
                policyFile.setOssbucket(OSSConfig.BUCKETNAME_XSJY_STATICSERVER);
                policyFile.setOssobjectkey(key);
                //policyFile.setFileSize();
                if(policyFileService.save(policyFile)){
                    returnmap.put("status", "1");
                    returnmap.put("msg", "文件上传成功");
                }

            } catch (OSSException e) {
                logger.error(e.getMessage());
                e.printStackTrace();
            } catch (ClientException e) {
                logger.error(e.getMessage());
                e.printStackTrace();
            } catch (IOException e) {
                logger.error(e.getMessage());
                e.printStackTrace();
            }

        }else{
            returnmap.put("msg", "非法访问");
        }
        System.out.println(JSONObject.toJSONString(returnmap));
        return JSONObject.toJSONString(returnmap);
    }
上面代码最主要是
OSSObjectUtils.putObject(OSSConfig.BUCKETNAME_XSJY_STATICSERVER, key, uploadfile.getInputStream());
OSSConfig.BUCKETNAME_XSJY_STATICSERVER:项目的静态服务器BUCKETNAME
OSSConfig.OBJECTKEY_PREFIX_FILE_POLICYFILE:key的前缀,BUCKETNAME后的文件夹
key:包含两个部分,前缀+文件名,文件名我才用的是UUID,避免出现同名问题。下载时通过之前保存的设置下载文件名
OSSObjectUtils.putObject()再传入流之后,上传就完成了。
但是为了保存一些属性方便以后下载使用。
FILE_PATH //阿里云地址
FILE_PATH_CUSTOMDOMAIN //域名地址
我选择一个测试文件来说明一下。
1)**FILE_PATH** :http://oss-cn-shanghai.aliyuncs.com/xsjyappstatic/file/policyfile/7ffd4732-5c54-45e6-b2d4-6553b3f5ccd1.jpg
2)**FILE_PATH_CUSTOMDOMAIN** :http://static01.xsjyapp.com/file/policyfile/7ffd4732-5c54-45e6-b2d4-6553b3f5ccd1.jpg

这两个地址都能访问到,只是阿里云地址会被一些DNS屏蔽。所以我们一般采用第二个,其实仔细可以发现。
http://oss-cn-shanghai.aliyuncs.com/xsjyappstatic==http://static01.xsjyapp.com
这之间是有映射关系的。
3)**FILE_PATH_RELATIVE**:
这个属性存储的是域名后的详细路径也就是两个地址相同的部分,如果以后更换项目域名,你会发现好处的。

再说下载

@RequestMapping(“/download”)//下载为html
public void download(HttpServletRequest request, HttpServletResponse response,
@RequestParam(“id”) Long id,
@RequestParam(“csrftoken”) String csrftoken) {

        String csrftoken_serssion = (String) request.getSession().getAttribute(com.unisolution.xsjy.jyj.helpers.SessionKeys.CSRFTOKEN);
        if(id!=null&&StringUtils.equals(csrftoken_serssion, csrftoken)){

            PolicyFile policyFile=policyFileService.getByPrimaryKey(id);

            if(policyFile!=null){
                String extname=StringUtils.substringAfterLast(policyFile.getFileNameOriginal(), ".");
                String encode_filename=StringUtils.substringBeforeLast(policyFile.getFileNameOriginal(), ".");
                try {
                    //encode_filename=URLEncoder.encode(StringUtils.substringBeforeLast(policyFile.getFileNameOriginal(), "."), "UTF-8");
                    //encode_filename=new String(StringUtils.substringBeforeLast(policyFile.getFileNameOriginal(), ".").getBytes(),"UTF-8");
                    encode_filename=encode_filename.replace(" ", "");
                    encode_filename = new String(encode_filename.getBytes("GB2312"), "ISO8859-1");
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.error(e.getMessage());
                    encode_filename=String.valueOf(new Date().getTime());
                }
                response.reset();
                //1.设置文件ContentType类型,这样设置,会自动判断下载文件类型  
                response.setContentType("application/octet-stream; charset=utf-8");  
                //2.设置文件头:最后一个参数是设置下载文件名(假如我们叫a.pdf)  
                response.setHeader("Content-Disposition", "attachment; filename="+encode_filename+"."+extname);  

                OutputStream out=null;
                try {
                    out=response.getOutputStream();
                    OSSObjectUtils.getObjectToOutputStream(policyFile.getOssbucket(), policyFile.getOssobjectkey(), out);
                } catch (IOException e) {
                    logger.error(e.getMessage());
                    e.printStackTrace();
                }finally{
                    try {
                        out.close();
                    } catch (IOException e) {
                        logger.error(e.getMessage());
                        e.printStackTrace();
                    }
                }

            }

        }
}

encode_filename写了好几次主要是火狐的不兼容,没有办法解析转过的文件名,以及文件名出现空格所出现的文件名不完整。为了这个搞了好久,看见火狐就头疼。
catch中的文件名是为了防止程序出错按照日期来设置默认文件名。
response.setHeader()是设置消息头filename后面的按照你的需要来,其他的按照这样写就写,为什么我也不知道,规范。

OutputStreamout=response.getOutputStream();
OSSObjectUtils.getObjectToOutputStream(policyFile.getOssbucket(), policyFile.getOssobjectkey(), out);
“`
这里面其实是要try catch的 为了简洁。。。。

通过rep获取输出流对象,然后就是OSSObjectUtils.getObjectToOutputStream();
第一个参数是bucketname 就是项目域名后存放的文件夹名
第二次参数是key 就是设置路径+整个文件名。
第三个就是传入输出流

猜你喜欢

转载自blog.csdn.net/dlovejava/article/details/73609176