关于阿里云OSS上传以及下载的处理方法
2017-06-22 17:48
381 查看
正好这个项目快结束了 ,被阿里云下载折腾了好久,网上相关支持又比较少,所有我结合自己的项目,简单的讲一下。 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 就是设置路径+整个文件名。
第三个就是传入输出流
相关文章推荐
- 关于委托、事件、处理事件的方法以及.NET 续一个实例
- 关于ActiveMQ接收消息,以及事务,hibernat事务的处理方法
- 关于多张图片的上传处理方法
- 安卓中关于图片从网络获取,压缩,上传,下载,缩略图,缓存的一些处理总结(一)
- 阿里云mysql数据库忘记密码处理方法以及用navicat远程登录mysql
- 关于在Cisco路由器接口上应用ip tcp adjust-mss命令后,TCP头中出现选项的解释以及处理方法
- 解析关于java,php以及html的所有文件编码与乱码的处理方法汇总
- 关于多张图片的上传处理方法
- (转)iPhone图片处理:摄像头/相册获取图片,压缩图片,上传服务器,下载,拉伸,方法总结
- 关于url传参乱码的解决方法以及文件流下载遇见的问题
- php中关于普通表单多文件上传的处理方法
- 关于ASP.NET中图片上传到MSSQL数据库以及读取的方法
- C#关于文件上传下载方法
- 基于Hadoop的云盘系统上传和下载效率优化及处理大量小文件的解决方法
- 自动化处理上传下载对话框的方法总结
- 文件上传 下载 一般处理程序和webForm联系以及asp.net内置对象
- 关于andriod sdk无法下载安装的处理方法
- 基于Hadoop的云盘系统上传和下载效率优化及处理大量小文件的解决方法
- 关于优酷视频上传失败或暂停之后一直处于上传中或者处理中删除不掉的解决方法
- 关于Spring jar包下载地址以及方法