阿里云Java上传文件(含解压zip)
1、maven
<dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>net.lingala.zip4j</groupId> <artifactId>zip4j</artifactId> <version>2.7.0</version> </dependency>
2、AliyunUploadController
package com.ruoyi.project.manage.controller; import ch.qos.logback.classic.Logger; import com.alibaba.fastjson.JSON; import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.project.manage.helper.AliyunUploadHelper; import com.ruoyi.project.manage.model.UploadFile; import com.ruoyi.project.tool.utils.LogbackUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; @RestController @RequestMapping("/manage/aliyunUpload") public class AliyunUploadController { private Logger log = LogbackUtil.getErrorLogger(); private SimpleDateFormat sdfSSS = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); @Autowired private AliyunUploadHelper aliyunUploadHelper; @RequestMapping("/uploadFile") @ResponseBody public AjaxResult upload(@RequestBody MultipartFile file, HttpServletRequest request) { AjaxResult ajaxResult = AjaxResult.success(); try { if (file == null || file.isEmpty()) { return AjaxResult.error("上传文件为空"); } AjaxResult AjaxResult_upload = aliyunUploadHelper.upload("uploadCard", file); if (!AjaxResult_upload.getCode().equals(0)) { return AjaxResult_upload; } List<UploadFile> uploadFiles = new ArrayList<>(); if (AjaxResult_upload.containsKey("listResult")) { List<Map<String, Object>> listResult = (List<Map<String, Object>>) AjaxResult_upload.getObjVal("listResult"); for (Map<String, Object> map : listResult) { UploadFile uploadFile = new UploadFile(); uploadFile.setUploadName(map.get("oldFileName").toString()); uploadFile.setFileName(map.get("newFileName").toString()); uploadFile.setUploadUrl(map.get("url").toString()); uploadFile.setTimeStamp(sdfSSS.format(new Date())); uploadFiles.add(uploadFile); } } else { UploadFile uploadFile = new UploadFile(); uploadFile.setUploadName(file.getOriginalFilename()); uploadFile.setFileName(AjaxResult_upload.getStrVal("newFileName").toString()); uploadFile.setUploadUrl(AjaxResult_upload.getStrVal("url").toString()); uploadFile.setTimeStamp(sdfSSS.format(new Date())); uploadFiles.add(uploadFile); } ajaxResult.put("uploadFiles", uploadFiles); } catch (Exception e) { e.printStackTrace(); ajaxResult = ajaxResult.error(e); } return ajaxResult; } @RequestMapping("/uploadFiles") @ResponseBody public AjaxResult uploadFiles(@RequestBody List<MultipartFile> fileList, HttpServletRequest request) { AjaxResult ajaxResult = AjaxResult.success(); try { if (fileList == null || fileList.isEmpty()) { return AjaxResult.error("上传文件为空"); } List<UploadFile> uploadFiles = new ArrayList<>(); for (MultipartFile multipartFile : fileList) { AjaxResult AjaxResult_upload = aliyunUploadHelper.upload("uploadCard", multipartFile); if (!AjaxResult_upload.getCode().equals(0)) { return AjaxResult_upload; } if (multipartFile.getOriginalFilename().endsWith(".zip") && AjaxResult_upload.containsKey("listResult")) { List<Map<String, Object>> listResult = (List<Map<String, Object>>) AjaxResult_upload.getObjVal("listResult"); for (Map<String, Object> map : listResult) { UploadFile uploadFile = new UploadFile(); uploadFile.setUploadName(map.get("oldFileName").toString()); uploadFile.setFileName(map.get("newFileName").toString()); uploadFile.setUploadUrl(map.get("url").toString()); uploadFile.setTimeStamp(sdfSSS.format(new Date())); uploadFiles.add(uploadFile); } } else { UploadFile uploadFile = new UploadFile(); uploadFile.setUploadName(multipartFile.getOriginalFilename()); uploadFile.setFileName(AjaxResult_upload.getStrVal("newFileName").toString()); uploadFile.setUploadUrl(AjaxResult_upload.getStrVal("url").toString()); uploadFile.setTimeStamp(sdfSSS.format(new Date())); uploadFiles.add(uploadFile); } } ajaxResult.put("uploadFiles", uploadFiles); log.info("返回的上传图片详情" + ajaxResult); } catch (Exception e) { e.printStackTrace(); ajaxResult = ajaxResult.errorMsg(e); } return ajaxResult; } //上传图片 @RequestMapping("/test01") @ResponseBody public String upload2() { AjaxResult ajaxResult = AjaxResult.success(); try { ajaxResult.put("newFileName", "newFileName"); ajaxResult.put("objectName", "objectName"); } catch (Exception e) { e.printStackTrace(); ajaxResult = ajaxResult.errorMsg(e); } return JSON.toJSONString(ajaxResult); } }
3、AliyunUploadHelper
package com.ruoyi.project.manage.helper; import ch.qos.logback.classic.Logger; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.model.GetObjectRequest; import com.aliyun.oss.model.OSSObject; import com.aliyun.oss.model.PutObjectResult; import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.project.tool.utils.FileUtil; import com.ruoyi.project.tool.utils.LogbackUtil; import com.ruoyi.project.tool.utils.ZipUtil; import org.apache.commons.io.FileUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.net.URL; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; import java.util.*; @Component public class AliyunUploadHelper { private Logger log = LogbackUtil.getErrorLogger(); // OSS所在服务区地址(在所购买的OSS存储对象空间信息中会有,一般也就是杭州的) private String endpoint = "oss-cn-beijing.aliyuncs.com"; // OSS对象存储空间访问身份验证账户和密钥 @Value("${aliYun.AccessKeyID}") private String accessKeyId; @Value("${aliYun.AccessKeySecret}") private String accessKeySecret; // OSS对象存储空间名 private String bucketName = "xxx-blck";//会诊/影像资料/文件名 private OSS ossClient; private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); private void initOss() { ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); } /** * 上传文件 * folder 一级路径名 multipartFile 上传文件 */ public AjaxResult upload(String folder, MultipartFile multipartFile) { AjaxResult ajaxResult = AjaxResult.success(); try { initOss(); if (multipartFile.getOriginalFilename().endsWith(".zip")) { String tmpZipFolder = FileUtil.getTempFolder("decompressFolderTemp"); String tmpFolderPath = FileUtil.getTempFolder("decompressFolder"); FileUtils.deleteDirectory(new File(tmpZipFolder)); FileUtils.deleteDirectory(new File(tmpFolderPath)); new File(tmpZipFolder).mkdir(); new File(tmpFolderPath).mkdir(); List<String> fileList = ZipUtil.unzip(multipartFile.getInputStream(), tmpZipFolder, multipartFile.getOriginalFilename()); List<Map<String, Object>> listResult = new ArrayList<>(); for (String filePath : fileList) { File currFile = new File(filePath); Map<String, Object> map = uploadInputStream(new FileInputStream(filePath), folder, currFile.getName()); listResult.add(map); currFile.delete(); } FileUtils.deleteDirectory(new File(tmpZipFolder)); ajaxResult.put("listResult", listResult); ajaxResult.put("fileList", fileList); } else { Map<String, Object> map = uploadInputStream(multipartFile.getInputStream(), folder, multipartFile.getOriginalFilename()); for (String key : map.keySet()) { ajaxResult.put(key, map.get(key)); } } } catch (Exception e) { e.printStackTrace(); ajaxResult = AjaxResult.error(e); } finally { ossClient.shutdown(); } return ajaxResult; } private Map<String, Object> uploadInputStream(InputStream inputStream, String folder, String fileName) { String extendName = fileName.substring(fileName.lastIndexOf(".")); String newFileName = UUID.randomUUID().toString().replace("-", "") + extendName; String objectName = folder + "/" + newFileName; //String contentType = getContentType(objectName); PutObjectResult objectResult = ossClient.putObject(bucketName, objectName, inputStream); Date expiration = new Date(System.currentTimeMillis() + 946080000 * 1000); ossClient.generatePresignedUrl(bucketName, objectName, expiration).toString(); //"http://taolihui-blck.oss-cn-beijing.aliyuncs.com/uploadCard/c255b71d230f4490a50ad461a7503e5e.jpg"; String url = "http://taolihui-blck.oss-cn-beijing.aliyuncs.com/" + objectName; objectResult.getETag(); Map<String, Object> map = new HashMap<>(); map.put("newFileName", newFileName); map.put("oldFileName", fileName); map.put("url", url); //map.put("contentType", contentType); //map.put("objectResult", objectResult); return map; } public AjaxResult upload(String folder, File file) { AjaxResult ajaxResult = AjaxResult.success(); try { initOss(); String extendName = file.getName().substring(file.getName().lastIndexOf(".")); String newFileName = UUID.randomUUID().toString().replace("-", "") + extendName; String objectName = folder + "/" + newFileName; String contentType = getContentType(objectName); PutObjectResult objectAjaxResult = ossClient.putObject(bucketName, objectName, new FileInputStream(file)); Date expiration = new Date(System.currentTimeMillis() + 946080000 * 1000); ossClient.generatePresignedUrl(bucketName, objectName, expiration).toString(); //"http://taolihui-blck.oss-cn-beijing.aliyuncs.com/uploadCard/c255b71d230f4490a50ad461a7503e5e.jpg"; String url = "http://taolihui-blck.oss-cn-beijing.aliyuncs.com/" + objectName; ajaxResult.put("newFileName", newFileName); ajaxResult.put("objectName", objectName); ajaxResult.put("url", url); //ajaxResult.put("contentType", contentType); //ajaxResult.put("objectAjaxResult", objectAjaxResult); } catch (Exception e) { e.printStackTrace(); ajaxResult = AjaxResult.error(e); } finally { ossClient.shutdown(); } return ajaxResult; } /** * 上传文件 * * @param objectName oss路径 * @param filePath 本地文件路径 * @return */ public Boolean upload(String objectName, String filePath) { initOss(); FileInputStream inputStream = null; try { inputStream = new FileInputStream(filePath); ossClient.putObject(bucketName, objectName, inputStream); inputStream.close(); return true; } catch (Exception e) { e.printStackTrace(); return false; } finally { ossClient.shutdown(); if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 生成下载url * * @param objectName oss路径 * @param expiration 失效时间 * @return */ public URL generatePresignedUrl(String objectName, Date expiration) { initOss(); try { return ossClient.generatePresignedUrl(bucketName, objectName, expiration); } finally { ossClient.shutdown(); } } /** * 下载文件 * * @param objectName oss路径 * @param filePath 下载文件存储路径 * @return */ public Boolean download(String objectName, String filePath) { initOss(); try { ossClient.getObject(new GetObjectRequest(bucketName, objectName), new File(filePath)); return true; } catch (Exception e) { e.printStackTrace(); return false; } finally { ossClient.shutdown(); } } /** * 下载文件 * * @param objectName 文件路径 * @param response */ public void download(String objectName, HttpServletResponse response) { initOss(); BufferedInputStream bis = null; OutputStream os = null; try { OSSObject ossObject = ossClient.getObject(new GetObjectRequest(bucketName, objectName)); // 读取文件内容(流) ossObject.getObjectContent() bis = new BufferedInputStream(ossObject.getObjectContent()); //获取完整对象名 String objectKey = ossObject.getKey(); //截取文件名 String fileName = objectKey.substring(objectKey.lastIndexOf("/") + 1, objectKey.length()); fileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()); response.reset(); response.setContentType("application/octet-stream"); response.setCharacterEncoding("utf-8"); //response.setContentLength((int) file.length()); response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ";filename*=UTF-8" + fileName); //解决跨域问题 response.addHeader("Access-Control-Allow-Origin", "*"); response.addHeader("Access-Control-Allow-Methods", "*"); response.addHeader("Access-Control-Allow-Headers", "*"); response.addHeader("Access-Control-Allow-Credentials", "true"); byte[] buff = new byte[1024]; os = response.getOutputStream(); int i = 0; while ((i = bis.read(buff)) != -1) { os.write(buff, 0, i); os.flush(); } } catch (Exception oe) { // 关闭 BufferedInputStream try { if (null != bis) { bis.close(); } } catch (IOException e) { log.error("下载文件报错"); } } finally { try { os.close(); bis.close(); } catch (IOException e) { log.error("关闭流文件失败"); } ossClient.shutdown(); } } public String genAttachmentFileName(String cnName, String defaultName) { try { // cnName = new String(cnName.getBytes(), StandardCharsets.UTF_8); cnName = new String(cnName.getBytes("gb2312"), "iso8859-1"); } catch (Exception e) { cnName = defaultName; } return cnName; } public static String getContentType(String fileNameExtension) { 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/jpg"; } 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 ""; } }
4、ZipUtil
package com.ruoyi.project.tool.utils; import net.lingala.zip4j.ZipFile; import net.lingala.zip4j.exception.ZipException; import net.lingala.zip4j.io.inputstream.ZipInputStream; import net.lingala.zip4j.model.FileHeader; import net.lingala.zip4j.model.LocalFileHeader; import org.slf4j.Logger; import org.springframework.web.multipart.MultipartFile; import java.io.*; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; public class ZipUtil { private static final Logger logger = LogbackUtil.getErrorLogger(); private final static String RIGHT_SLASH = "/"; private final static String DOUBLE_LEFT_SLASH = "\\\\"; private final static String LEFT_SLASH = "\\"; private final static String CHARSET_GBK = "GBK"; public static void main(String[] args) { String zipPath = "C:\\Users\\K\\Desktop\\新建文件3夹.zip"; String tmpFolderPath = FileUtil.getTempFolder("decompressFolder"); List<String> list = new ArrayList<>(); unzip(zipPath, tmpFolderPath, list); list.forEach(a -> System.out.println("path=" + a)); } public static List<String> unzip(InputStream inputStream, String destFolder, String fileName) { String destFilePath = destFolder + File.separator + fileName; String res = FileUtil.saveFile(inputStream, destFilePath); if (res.startsWith("-1")) { return new ArrayList<>(); } String tmpFolderPath = FileUtil.getTempFolder("decompressFolder"); List<String> list = new ArrayList<>(); unzip(destFilePath, tmpFolderPath, list); return list; } /** * 根据文件全路径将zip文件解压到一个文件路径下 * * @param realPath * @param destFolder */ public static void unzip(String realPath, String destFolder, List<String> files) { try { logger.info("解压开始:" + System.currentTimeMillis()); ZipFile zipFile = new ZipFile(realPath); zipFile.setCharset(Charset.forName(CHARSET_GBK)); zipFile.extractAll(destFolder); // 获取ZIP中所有文件的FileHeader,以便后面对zip中文件进行遍历 List<FileHeader> list = zipFile.getFileHeaders(); logger.info("解压结束:" + System.currentTimeMillis()); list.forEach(fileHeadr -> { String fileName = fileHeadr.getFileName(); //zip压缩文件里面的文件列表 //如果是目录不做处理 if (fileName.endsWith(RIGHT_SLASH) || fileName.endsWith(DOUBLE_LEFT_SLASH) || fileName.endsWith(LEFT_SLASH)) { logger.info("这是一个文件夹:" + fileName); } else if (fileName.endsWith(".zip")) { try { String zip2FilePath = destFolder + File.separator + fileName; unzip(zip2FilePath, destFolder, files); new File(zip2FilePath).delete(); } catch (Exception e) { e.printStackTrace(); } } else { //如果不是文件夹,将文件信息放入文件列表容器 files.add(destFolder + File.separator + fileName); } }); } catch (ZipException e) { logger.error("unzip file[{}] has error", realPath, e); } } /** * 前端传入File类型文件 * * @param multipartFile */ public static List<String> unzipByFile(MultipartFile multipartFile, String destFolder) { try { logger.info("解压开始:" + System.currentTimeMillis()); List<String> files = new ArrayList<>(); //将存放在服务器的文件路径 String dateStr = String.valueOf(System.currentTimeMillis()); //String tempDirectory = FileUtils.getTempDirectoryPath(); //Windows系统文件路径 String filePath = destFolder + File.separator + "Housing_System_Zip_" + dateStr; //logger.info("临时文件目录:"+tempDirectory+";压缩文件解压路径:"+filePath); //multipartFile转成File File file = new File(filePath + File.separator + multipartFile.getOriginalFilename()); //FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), file); ZipFile zipFile = new ZipFile(file); if (!testEncoding(filePath + File.separator + multipartFile.getOriginalFilename(), StandardCharsets.UTF_8)) { zipFile.setCharset(Charset.forName(CHARSET_GBK)); } zipFile.extractAll(filePath); // 获取ZIP中所有文件的FileHeader,以便后面对zip中文件进行遍历 List<FileHeader> list = zipFile.getFileHeaders(); list.forEach(fileHeadr -> { String fileName = fileHeadr.getFileName(); //zip压缩文件里面的文件列表 //如果是目录不做处理 if (fileName.endsWith(RIGHT_SLASH) || fileName.endsWith(DOUBLE_LEFT_SLASH) || fileName.endsWith(LEFT_SLASH)) { logger.info("这是一个文件夹:" + fileName); } else { //如果不是文件夹,将文件信息放入文件列表容器 files.add(filePath + File.separator + fileName); } }); logger.info("解压结束:" + System.currentTimeMillis()); return files; } catch (ZipException e) { logger.error("unzipByFile file[{}] has error", multipartFile, e); } catch (IOException e) { logger.error("multipartFile to File has error", e); } return null; } /** * 文件字符集判断 * * @param filepath * @param charset * @return * @throws FileNotFoundException */ private static boolean testEncoding(String filepath, Charset charset) throws FileNotFoundException { FileInputStream fis = new FileInputStream(new File(filepath)); BufferedInputStream bis = new BufferedInputStream(fis); ZipInputStream zis = new ZipInputStream(bis, charset); LocalFileHeader zn = null; try { while ((zn = zis.getNextEntry()) != null) { logger.info("check file charset"); } } catch (Exception e) { return false; } finally { try { zis.close(); bis.close(); fis.close(); } catch (IOException e) { e.printStackTrace(); } } return true; } }
5、FileUtil
package com.ruoyi.project.tool.utils; import com.ruoyi.project.tool.utils.other.DateUtil; import com.ruoyi.project.tool.utils.other.ParseUtils; import org.apache.commons.lang3.StringUtils; import java.io.*; import java.util.*; public class FileUtil { public static String getTempFolder(String lastFolder) { String tmpFolderPath = System.getProperty("java.io.tmpdir") + File.separator + lastFolder; File tmpFolder = new File(tmpFolderPath); if (!tmpFolder.exists()) { tmpFolder.mkdir(); } return tmpFolder.getPath(); } public static String saveFile(InputStream inputStream, String destPath) { String res = "-1"; FileOutputStream outputStream = null; try { outputStream = new FileOutputStream(destPath); byte[] b = new byte[1024]; while ((inputStream.read(b)) != -1) { outputStream.write(b);// 写入数据 } inputStream.close(); outputStream.close();// 保存数据 res = "1"; } catch (Exception e) { e.printStackTrace(); res = "-1 " + e.getMessage(); } return res; } }
6、UploadFile
package com.ruoyi.project.manage.model; import java.io.Serializable; public class UploadFile implements Serializable { private Integer uploadId;//上传文件的id private String uploadName;//上传文件的名称 private String uploadUrl;//上传文件的url private String timeStamp;//时间戳 private String fileName;//文件生成的名称 private int angel;//旋转的角度 public String getFileName() { return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } public Integer getUploadId() { return uploadId; } public void setUploadId(Integer uploadId) { this.uploadId = uploadId; } public String getUploadName() { return uploadName; } public void setUploadName(String uploadName) { this.uploadName = uploadName; } public String getUploadUrl() { return uploadUrl; } public void setUploadUrl(String uploadUrl) { this.uploadUrl = uploadUrl; } public String getTimeStamp() { return timeStamp; } public void setTimeStamp(String timeStamp) { this.timeStamp = timeStamp; } public int getAngel() { return angel; } public void setAngel(int angel) { this.angel = angel; } @Override public String toString() { return "UploadFile{" + "uploadId=" + uploadId + ", uploadName='" + uploadName + '\'' + ", uploadUrl='" + uploadUrl + '\'' + ", timeStamp='" + timeStamp + '\'' + ", fileName='" + fileName + '\'' + ", angel=" + angel + '}'; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了