package com.izouma.awesomeadmin.service; import com.aliyun.oss.OSSClient; import com.aliyun.oss.model.OSSObject; import com.aliyun.oss.model.ObjectMetadata; import com.aliyun.oss.model.PutObjectResult; import com.izouma.awesomeadmin.util.ImagesUtil; import com.izouma.awesomeadmin.util.PropertiesFileLoader; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.net.URLEncoder; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.Random; import java.util.zip.Adler32; import java.util.zip.CheckedOutputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; @Service public class OSSFileService { /** * 日志对象 */ private static Logger logger = Logger.getLogger(OSSFileService.class); private static final String projectName = PropertiesFileLoader.getProperties("projectname"); public String upload(InputStream fin, String path) { if (path.startsWith("/")) { path = path.replaceFirst("\\\\/", ""); } path = projectName + "/" + path; String aliid = PropertiesFileLoader.getDefaultProperties("aliossid", ""); String alikey = PropertiesFileLoader.getDefaultProperties("aliosskey", ""); String aliossendpoit = "Y".equals(PropertiesFileLoader.getDefaultProperties("alioss_internal_flag", "")) ? PropertiesFileLoader.getDefaultProperties("aliossendpoitinternal", "") : PropertiesFileLoader.getDefaultProperties("aliossendpoit", ""); String bucketname = PropertiesFileLoader.getDefaultProperties("alibucketname", ""); logger.info(String.format("OSS上传:\naliid: %s\nalikey: %s\naliossendpoit: %s\nbucketname: %s\npath: %s", aliid, alikey, aliossendpoit, bucketname, path)); OSSClient client = new OSSClient(aliossendpoit, aliid, alikey); OSSObject object = null; boolean found = false; try { PutObjectResult result = client.putObject(bucketname, path, fin, new ObjectMetadata()); //object = client.getObject(bucketname, path); // 判断文件是否存在。doesObjectExist还有一个参数isOnlyInOSS,如果为true则忽略302重定向或镜像;如果为false,则考虑302重定向或镜像。 found = client.doesObjectExist(bucketname, path); System.out.println(found + "path"); } catch (Exception r) { logger.error("OSS上传异常:", r); } finally { try { fin.close(); } catch (IOException e) { e.printStackTrace(); } } client.shutdown(); // 如果不设置content-length, 默认为chunked编码。 if (found) { return getFullPath(path); } return null; } private static String getFullPath(String Path) { if (Path == null || "".equals(Path)) { return Path; } String aliossendpoit = PropertiesFileLoader.getDefaultProperties("aliImageSever", ""); return aliossendpoit + "/" + Path; } public String uploadImg(String base64) throws UnsupportedEncodingException { try { logger.info("uploadIcon:上传图片"); if (base64 == null) { return null; } Random random = new Random(); StringBuilder randomCode = new StringBuilder(); for (int i = 0; i < 8; i++) { randomCode.append(Integer.toString(random.nextInt(36), 36)); } try { String path = String.format("images/%s-%s.jpg", new SimpleDateFormat("yyyy-MM-dd-hh-mm-ss").format(new Date()), randomCode); return upload(ImagesUtil.GenerateImage(base64), path); } catch (Exception e) { e.printStackTrace(); } } catch (Exception e) { e.printStackTrace(); logger.error("上传图片异常"); } return null; } /** * @param objectName 不包含 bucketname 的 path */ public void deleteObject(String objectName) { if (StringUtils.isNotEmpty(objectName)) { String aliid = PropertiesFileLoader.getDefaultProperties("aliossid", ""); String alikey = PropertiesFileLoader.getDefaultProperties("aliosskey", ""); String aliossendpoit = PropertiesFileLoader.getDefaultProperties("aliossendpoit", ""); String bucketname = PropertiesFileLoader.getDefaultProperties("alibucketname", ""); logger.info(String.format("OSS 删除:\naliid: %s\nalikey: %s\naliossendpoit: %s\nbucketname: %s\npath: %s", aliid, alikey, aliossendpoit, bucketname, objectName)); OSSClient client = new OSSClient(aliossendpoit, aliid, alikey); // 删除文件。 client.deleteObject(bucketname, objectName); // 关闭OSSClient。 client.shutdown(); } } /** * 批量下载图片 * * @param keyList ossfileName 逗号分隔。 * @param zipName 压缩包名称 * @param request * @param response * @return */ public HttpServletResponse zipFilesDown(List keyList, String zipName, HttpServletRequest request, HttpServletResponse response) { String accessKeyId = PropertiesFileLoader.getDefaultProperties("aliossid", ""); String accessKeySecret = PropertiesFileLoader.getDefaultProperties("aliosskey", ""); String endpoint = "Y".equals(PropertiesFileLoader.getDefaultProperties("alioss_internal_flag", "")) ? PropertiesFileLoader.getDefaultProperties("aliossendpoitinternal", "") : PropertiesFileLoader.getDefaultProperties("aliossendpoit", ""); String bucketName = PropertiesFileLoader.getDefaultProperties("alibucketname", ""); // endpoint以杭州为例,其它region请按实际情况填写 // 云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,创建并使用RAM子账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建 try { // 初始化 OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret); String fileName = zipName + ".zip"; // 创建临时文件 File zipFile = File.createTempFile(zipName, ".zip"); FileOutputStream f = new FileOutputStream(zipFile); /** * 作用是为任何OutputStream产生校验和 * 第一个参数是制定产生校验和的输出流,第二个参数是指定Checksum的类型 (Adler32(较快)和CRC32两种) */ CheckedOutputStream csum = new CheckedOutputStream(f, new Adler32()); // 用于将数据压缩成Zip文件格式 ZipOutputStream zos = new ZipOutputStream(csum); for (String ossfile : keyList) { try { // 获取Object,返回结果为OSSObject对象 OSSObject ossObject = ossClient.getObject(bucketName, ossfile); // 读去Object内容 返回 InputStream inputStream = ossObject.getObjectContent(); // 对于每一个要被存放到压缩包的文件,都必须调用ZipOutputStream对象的putNextEntry()方法,确保压缩包里面文件不同名 zos.putNextEntry(new ZipEntry(ossfile.split("/")[ossfile.split("/").length - 1])); int bytesRead = 0; // 向压缩文件中输出数据 while ((bytesRead = inputStream.read()) != -1) { zos.write(bytesRead); } inputStream.close(); zos.closeEntry(); // 当前文件写完,定位为写入下一条项目 } catch (Exception e) { logger.error("ossfile, 压缩失败", e); } } zos.close(); String header = request.getHeader("User-Agent").toUpperCase(); if (header.contains("MSIE") || header.contains("TRIDENT") || header.contains("EDGE")) { fileName = URLEncoder.encode(fileName, "utf-8"); fileName = fileName.replace("+", "%20"); //IE下载文件名空格变+号问题 } else { fileName = new String(fileName.getBytes(), "ISO8859-1"); } response.reset(); response.setContentType("text/plain"); response.setContentType("application/octet-stream; charset=utf-8"); response.setHeader("Location", fileName); response.setHeader("Cache-Control", "max-age=0"); response.setHeader("Content-Disposition", "attachment; filename=" + fileName); FileInputStream fis = new FileInputStream(zipFile); BufferedInputStream buff = new BufferedInputStream(fis); BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream()); byte[] car = new byte[1024]; int l = 0; while (l < zipFile.length()) { int j = buff.read(car, 0, 1024); l += j; out.write(car, 0, j); } // 关闭流 fis.close(); buff.close(); out.close(); ossClient.shutdown(); // 删除临时文件 zipFile.delete(); } catch (Exception e) { logger.error("压缩失败", e); } return response; } /** * 单张图片下载 * * @param key * @param request * @param response * @return */ public HttpServletResponse singleFileDown(String key, HttpServletRequest request, HttpServletResponse response) { String accessKeyId = PropertiesFileLoader.getDefaultProperties("aliossid", ""); String accessKeySecret = PropertiesFileLoader.getDefaultProperties("aliosskey", ""); String endpoint = "Y".equals(PropertiesFileLoader.getDefaultProperties("alioss_internal_flag", "")) ? PropertiesFileLoader.getDefaultProperties("aliossendpoitinternal", "") : PropertiesFileLoader.getDefaultProperties("aliossendpoit", ""); String bucketName = PropertiesFileLoader.getDefaultProperties("alibucketname", ""); // endpoint以杭州为例,其它region请按实际情况填写 // 云账号AccessKey有所有API访问权限,建议遵循阿里云安全最佳实践,创建并使用RAM子账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建 try { // 初始化 OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret); // 获取Object,返回结果为OSSObject对象 OSSObject ossObject = ossClient.getObject(bucketName, key); // 读去Object内容 返回 InputStream inputStream = ossObject.getObjectContent(); // 对于每一个要被存放到压缩包的文件,都必须调用ZipOutputStream对象的putNextEntry()方法,确保压缩包里面文件不同名 String fileName = key.split("/")[key.split("/").length - 1]; String header = request.getHeader("User-Agent").toUpperCase(); if (header.contains("MSIE") || header.contains("TRIDENT") || header.contains("EDGE")) { fileName = URLEncoder.encode(fileName, "utf-8"); fileName = fileName.replace("+", "%20"); //IE下载文件名空格变+号问题 } else { fileName = new String(fileName.getBytes(), "ISO8859-1"); } response.reset(); response.setContentType("text/plain"); response.setContentType("application/octet-stream; charset=utf-8"); response.setHeader("Location", fileName); response.setHeader("Cache-Control", "max-age=0"); response.setHeader("Content-Disposition", "attachment; filename=" + fileName); BufferedInputStream buff = new BufferedInputStream(inputStream); BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream()); byte[] car = new byte[1024]; int l = 0; while ((l = inputStream.read(car)) != -1) { if (car.length != 0) { out.write(car, 0, l); } } // 关闭流 inputStream.close(); buff.close(); out.close(); ossClient.shutdown(); } catch (Exception e) { logger.error("下载图片失败", e); } return response; } public boolean doesObjectExist(String path) { String aliid = PropertiesFileLoader.getDefaultProperties("aliossid", ""); String alikey = PropertiesFileLoader.getDefaultProperties("aliosskey", ""); String aliossendpoit = "Y".equals(PropertiesFileLoader.getDefaultProperties("alioss_internal_flag", "")) ? PropertiesFileLoader.getDefaultProperties("aliossendpoitinternal", "") : PropertiesFileLoader.getDefaultProperties("aliossendpoit", ""); String bucketname = PropertiesFileLoader.getDefaultProperties("alibucketname", ""); logger.info(String.format("OSS上传:\naliid: %s\nalikey: %s\naliossendpoit: %s\nbucketname: %s\npath: %s", aliid, alikey, aliossendpoit, bucketname, path)); OSSClient client = new OSSClient(aliossendpoit, aliid, alikey); boolean found = false; // 判断文件是否存在。doesObjectExist还有一个参数isOnlyInOSS,如果为true则忽略302重定向或镜像;如果为false,则考虑302重定向或镜像。 found = client.doesObjectExist(bucketname, path); System.out.println(found + "path"); client.shutdown(); return found; } }