强烈推荐一个大神的人工智能的教程:http://www.captainai.net/zhanghan
【前言】
我们上家公司的存储系统用的是FastDFS(智能一代云平台(二十八):对前后端分离和FastDFS的使用的再理解);现在在职的公司用的是阿里云的OSS(OSS的官方文档),在工作的时候整理一个上传OSS文件的工具类,现在与大家分享一下。
【工具类】
1、工具类的代码:
packagezhanghan.oss.utils; importcom.aliyun.oss.ClientException; importcom.aliyun.oss.OSSClient; importcom.aliyun.oss.OSSException; importcom.aliyun.oss.model.ObjectMetadata; importcom.aliyun.oss.model.PutObjectResult; importcom.fasterxml.jackson.annotation.JsonValue; importorg.apache.commons.io.FilenameUtils; importorg.apache.commons.lang3.time.DateUtils; importorg.springframework.util.StringUtils; importorg.springframework.web.multipart.MultipartFile; importzhanghan.oss.exception.OSSCreateBucketRuntimeException; importzhanghan.oss.exception.OSSGeneratePresignedUrlRuntimeException; importzhanghan.oss.exception.OssPutObjectRuntimeException; importjava.io.InputStream; importjava.net.URL; importjava.util.Date; importjava.util.UUID; /*** OSS上传工具类-张晗-2017/10/10*/publicclassOSSUtil { privatevolatilestaticOSSClientinstance; privateOSSUtil() { } /*** 单例* @return OSS工具类实例*/privatestaticOSSClientgetOSSClient() { if (instance==null) { synchronized (OSSUtil.class) { if (instance==null) { instance=newOSSClient(OSS_END_POINT, OSS_ACCESS_KEY_ID, OSS_ACCESS_KEY_SECRET); } } } returninstance; } //定义日志privatefinalstaticLogUtilslogger=LogUtils.getLogger(OSSUtil.class); //OSS 的地址privatefinalstaticStringOSS_END_POINT="http://oss-cn-qingdao.aliyuncs.com"; //OSS 的key值privatefinalstaticStringOSS_ACCESS_KEY_ID="OSSKEY"; //OSS 的secret值privatefinalstaticStringOSS_ACCESS_KEY_SECRET="OSSSECRET"; //OSS 的bucket名字privatefinalstaticStringOSS_BUCKET_NAME="zhanghan-test"; //设置URL过期时间为10年privatefinalstaticDateOSS_URL_EXPIRATION=DateUtils.addDays(newDate(), 365*10); //文件路径的枚举publicenumFileDirType { ZHANGHAN_TEST("test"); privateStringdir; FileDirType(Stringdir) { this.dir=dir; } publicStringgetDir() { returndir; } } /*** 上传文件---去除URL中的?后的时间戳* @param file 文件* @param fileDir 上传到OSS上文件的路径* @return 文件的访问地址*/publicstaticStringupload(MultipartFilefile, FileDirTypefileDir) { OSSUtil.createBucket(); StringfileName=OSSUtil.uploadFile(file, fileDir); StringfileOssURL=OSSUtil.getImgUrl(fileName, fileDir); intfirstChar=fileOssURL.indexOf("?"); if (firstChar>0) { fileOssURL=fileOssURL.substring(0, firstChar); } returnfileOssURL; } /*** 当Bucket不存在时创建Bucket** @throws OSSException 异常* @throws ClientException Bucket命名规则:* 1.只能包含小写字母、数字和短横线,* 2.必须以小写字母和数字开头和结尾* 3.长度在3-63之间*/privatestaticvoidcreateBucket() { try { if (!OSSUtil.getOSSClient().doesBucketExist(OSS_BUCKET_NAME)) {//判断是否存在该Bucket,不存在时再重新创建OSSUtil.getOSSClient().createBucket(OSS_BUCKET_NAME); } } catch (Exceptione) { logger.error("{}", "创建Bucket失败,请核对Bucket名称(规则:只能包含小写字母、数字和短横线,必须以小写字母和数字开头和结尾,长度在3-63之间)"); thrownewOSSCreateBucketRuntimeException("创建Bucket失败,请核对Bucket名称(规则:只能包含小写字母、数字和短横线,必须以小写字母和数字开头和结尾,长度在3-63之间)"); } } /*** 上传到OSS服务器 如果同名文件会覆盖服务器上的* @param file 文件* @param fileDir 上传到OSS上文件的路径* @return 文件的访问地址*/privatestaticStringuploadFile(MultipartFilefile, FileDirTypefileDir) { StringfileName=String.format( "%s.%s", UUID.randomUUID().toString(), FilenameUtils.getExtension(file.getOriginalFilename())); try (InputStreaminputStream=file.getInputStream()) { //创建上传Object的MetadataObjectMetadataobjectMetadata=newObjectMetadata(); objectMetadata.setContentLength(inputStream.available()); objectMetadata.setCacheControl("no-cache"); objectMetadata.setHeader("Pragma", "no-cache"); objectMetadata.setContentType(getContentType(FilenameUtils.getExtension("."+file.getOriginalFilename()))); objectMetadata.setContentDisposition("inline;filename="+fileName); //上传文件PutObjectResultputResult=OSSUtil.getOSSClient().putObject(OSS_BUCKET_NAME, fileDir.getDir() +fileName, inputStream, objectMetadata); returnfileName; } catch (Exceptione) { logger.error("{}", "上传文件失败"); thrownewOssPutObjectRuntimeException("上传文件失败"); } } /*** 获得文件路径* @param fileUrl 文件的URL* @param fileDir 文件在OSS上的路径* @return 文件的路径*/privatestaticStringgetImgUrl(StringfileUrl, FileDirTypefileDir) { if (StringUtils.isEmpty(fileUrl)) { logger.error("{}", "文件地址为空"); thrownewRuntimeException("文件地址为空"); } String[] split=fileUrl.split("/"); //获取oss图片URL失败URLurl=OSSUtil.getOSSClient().generatePresignedUrl(OSS_BUCKET_NAME, fileDir.getDir() +split[split.length-1], OSS_URL_EXPIRATION); if (url==null) { logger.error("{}", "获取oss文件URL失败"); thrownewOSSGeneratePresignedUrlRuntimeException("获取oss文件URL失败"); } returnurl.toString(); } /*** 判断OSS服务文件上传时文件的contentType** @param FilenameExtension 文件后缀* @return 后缀*/privatestaticStringgetContentType(StringFilenameExtension) { if (FilenameExtension.equalsIgnoreCase("bmp")) { return"image/bmp"; } if (FilenameExtension.equalsIgnoreCase("gif")) { return"image/gif"; } if (FilenameExtension.equalsIgnoreCase("jpeg") ||FilenameExtension.equalsIgnoreCase("jpg") ||FilenameExtension.equalsIgnoreCase("png")) { return"image/jpeg"; } if (FilenameExtension.equalsIgnoreCase("html")) { return"text/html"; } if (FilenameExtension.equalsIgnoreCase("txt")) { return"text/plain"; } if (FilenameExtension.equalsIgnoreCase("vsd")) { return"application/vnd.visio"; } if (FilenameExtension.equalsIgnoreCase("pptx") ||FilenameExtension.equalsIgnoreCase("ppt")) { return"application/vnd.ms-powerpoint"; } if (FilenameExtension.equalsIgnoreCase("docx") ||FilenameExtension.equalsIgnoreCase("doc")) { return"application/msword"; } if (FilenameExtension.equalsIgnoreCase("xml")) { return"text/xml"; } return"image/jpeg"; } }
2、调用工具类的代码:
/*** 上传文件测试* @param multipartFile 待上传的文件* @return 上传在OSS文件的访问路径* @throws BusinessException 上传异常*/publicStringuploadTest(MultipartFilemultipartFile) throwsBusinessException{ try { uploadResult=OSSUtil.upload(multipartFile, OSSUtil.FileDirType.ZHANGHAN_TEST); } catch (Exceptione) { LoggerUtil.logService(LoggerUtil.spManualLoan, "SPManualLoanServiceImpl-submitLoan", "call OSSUtil.upload; Exception:"+e.getMessage()); thrownewBusinessException(WrongMessageEnum.EXCEPTION_STORE); } returnuploadResult; }
3、问题&解决:
(1) 问题:通过URL在浏览器中访问时报如下错:
(2)解决方案:在阿里云的控制台上,进入OSS的设置界面,将Bucket的访问权限由 私有 设置为 公共读
【总结】
阿里云现在很多公司都在用,阿里云稳定,安全,相对来说成本更低;给自己更多思考的是如何让项目减少成本,以及阿里云等带来的商业模式。