springboot实现json文件生成,压缩为zip文件并在浏览器下载

示例

@RestController
public class FileController {
    private static final Logger logger = LoggerFactory.getLogger(FileController.class);

    private static final String filePath = "/fileTemp";
    @Autowired
    private ObjectMapper objectMapper;

    @GetMapping("/v1/file/add")
    public void add() {

    }

    @GetMapping("/v1/file/zip")
    public ResponseEntity<byte[]> zip() {
        File tempJSONFile, tempPngFile;
        String outputFileName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        try {
            // 创建临时文件根目录
            File tempFileDirectory = new File(filePath);
            if (!tempFileDirectory.exists()) {
                boolean dirCreateFlag = tempFileDirectory.mkdirs();
                logger.info("临时文件目录创建成功: {}", dirCreateFlag);
            }
            // JSON数据
            Map<String, String> data = new HashMap<>();
            data.put("1", "1");
            for (int i = 0; i < 10; i++) {
                // json文件
                tempJSONFile = createJsonFile(i, "deviceId_" + i + ".json", objectMapper.writeValueAsString(data));
                if (tempJSONFile.exists()) {
                    logger.info("JSON文件已创建");
                } else {
                    logger.info("JSON文件未创建");
                }
                // 图片文件 http://app.test.stesh.cn/images/zjlogo.png
                ImageTool.downloadImage("http://app.test.stesh.cn/images/zjlogo.png", filePath + "/" + i ,"deviceId_" + i + ".png");
            }
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
//            ZipOutputStream zos = new ZipOutputStream(baos);
//            zipDirectory(tempFileDirectory, zos);
//            zos.close();
            ZipTool.createZipFile(tempFileDirectory, baos);
            // 删除目录
            deleteDirectory(tempFileDirectory);
            HttpHeaders headers = new HttpHeaders();
            headers.add("Content-Disposition", "attachment; filename=" + outputFileName + ".zip");
            return ResponseEntity.ok()
                    .headers(headers)
                    .contentLength(baos.size())
                    .body(baos.toByteArray());
        } catch (IOException e) {
            e.printStackTrace();
            logger.info("error: {}", e.getMessage());
        } finally {

        }
        return null;
    }

    public void zipDirectory(File directory, ZipOutputStream zos) throws IOException {
        // zipFiles(directory, directory.getName(), zos);
        // 压缩时不带根目录
        zipFiles(directory, "", zos);
        zos.close();
    }

    private void zipFiles(File directory, String baseName, ZipOutputStream zos) throws IOException {
        File[] files = directory.listFiles();
        byte[] buffer = new byte[1024];
        int length;
        for (File file : files) {
            if (file.isDirectory()) {
                // 如果baseName不为空,则保留除根目录外的子目录结构
                // 否则,不添加任何前缀到子目录的zip条目中
                logger.info("baseName:{}", baseName);
                String subDirName = (baseName.isEmpty() ? "" : baseName + "/") + file.getName();
                zipFiles(file, subDirName, zos);
                continue;
            }
            // 直接使用文件名作为ZipEntry的名称,去掉根目录部分
            ZipEntry zipEntry = new ZipEntry(baseName.isEmpty() ? file.getName() : baseName + "/" + file.getName());
            zos.putNextEntry(zipEntry);
            try (FileInputStream fis = new FileInputStream(file)) {
                while ((length = fis.read(buffer)) > 0) {
                    zos.write(buffer, 0, length);
                }
            }
            zos.closeEntry();
        }
    }

    public File createJsonFile(Integer i, String fileName, String jsonString) throws IOException {
        // 创建本地临时文件
        // 创建文件目录
        File tempFileDirectory = new File(filePath + "/" + i);
        if (!tempFileDirectory.exists()) {
            boolean dirCreateFlag = tempFileDirectory.mkdirs();
            logger.info("临时文件目录创建成功: {}", dirCreateFlag);
        }
        File jsonFile = new File(filePath + "/" + i + "/" + fileName);
        try (FileWriter fileWriter = new FileWriter(jsonFile)) {
            fileWriter.write(jsonString);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return jsonFile;
    }

    public static void deleteDirectory(File directory) {
        if (directory.exists()) {
            File[] files = directory.listFiles();
            if (files != null) {
                for (File file : files) {
                    if (file.isDirectory()) {
                        // 递归删除子目录
                        deleteDirectory(file);
                    } else {
                        // 删除文件
                        file.delete();
                    }
                }
            }
            // 最后删除目录本身
            directory.delete();
        }
    }

    private String get(String url, Map<String, String> headers, Map<String, String> querys) {
        HttpClient httpClient = null;
        HttpGet httpGet = null;
        String result = null;
        try {
            httpClient = new SSLClient();
            URIBuilder builder = new URIBuilder(url);
            if (!CollectionUtils.isEmpty(querys)) {
                for (String key : querys.keySet()) {
                    builder.setParameter(key, String.valueOf(querys.get(key)));
                }
            }
            httpGet = new HttpGet(builder.build());
            if (!CollectionUtils.isEmpty(headers)) {
                // 设置header
                for (String headerName : headers.keySet()) {
                    httpGet.addHeader(headerName, headers.get(headerName));
                }
            }
            // 设置超时时间
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(3000).setConnectionRequestTimeout(1000)
                    .setSocketTimeout(10000).build();
            httpGet.setConfig(requestConfig);
            HttpResponse response = httpClient.execute(httpGet);
            if (response != null) {
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    result = EntityUtils.toString(resEntity, "UTF-8");
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return result;
    }
}

http下载图片并写入文件

public class ImageTool {
    public static void downloadImage(String imageUrl, String saveFilePath, String fileName) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(imageUrl);
        try {
            CloseableHttpResponse response = httpClient.execute(httpGet);
            File tempFileDirectory = new File(saveFilePath);
            System.out.println("path:" + tempFileDirectory.getAbsolutePath());
            if (!tempFileDirectory.exists()) {
                boolean dirCreateFlag = tempFileDirectory.mkdirs();
            }
            FileOutputStream fos = new FileOutputStream(saveFilePath + "/" + fileName);
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                // 将图片内容写入文件
                entity.writeTo(fos);
                System.out.println("Image downloaded successfully!");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (httpClient != null) {
                    httpClient.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

将文件压缩为zip文件

public class ZipTool {

    public static void zipFiles(File directory, String baseName, ZipArchiveOutputStream zos) throws IOException {
        File[] files = directory.listFiles();
        if (files == null) {
            return; // 可能是目录不存在或没有读取权限
        }

        for (File file : files) {
            Path filePath = file.toPath();
            String entryName = baseName.isEmpty() ? filePath.getFileName().toString() : baseName + "/" + filePath.getFileName().toString();

            if (Files.isDirectory(filePath)) {
                // 递归处理子目录
                ZipArchiveEntry dirEntry = new ZipArchiveEntry(entryName + "/"); // 注意添加斜杠以表示目录
                zos.putArchiveEntry(dirEntry);
                zos.closeArchiveEntry();
                zipFiles(file, entryName, zos);
                continue;
            }

            // 处理文件
            ZipArchiveEntry fileEntry = new ZipArchiveEntry(entryName);
            zos.putArchiveEntry(fileEntry);

            try (InputStream fis = Files.newInputStream(filePath)) {
                byte[] buffer = new byte[1024];
                int length;
                while ((length = fis.read(buffer)) > 0) {
                    zos.write(buffer, 0, length);
                }
            }
            zos.closeArchiveEntry();
        }
    }

    // 示例方法,用于创建ZIP文件并调用zipFiles方法
    public static void createZipFile(File directory, ByteArrayOutputStream byteArrayOutputStream) {
        ZipArchiveOutputStream zos = null;
        try {
            zos = new ZipArchiveOutputStream(byteArrayOutputStream);
            // 假设我们不想在ZIP中包含根目录本身
            zipFiles(directory, "", zos);
        } catch (IOException e){
            e.printStackTrace();
        } finally {
            try {
                if (zos != null) {
                    zos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/746469.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

观测云 VS 开源自建

观测云是一款面向全技术栈的监控观测一体化产品方案&#xff0c;具备强大而丰富的功能&#xff0c;目标是帮助最终用户提升监控观测的能力&#xff0c;化繁为简&#xff0c;轻松的构建起完整的监控观测体系。同时能够帮助整个企业的开发技术团队从统一的观测能力上获得完整的收…

ONLYOFFICE 文档开发者版 8.1:API 更新

随着版本 8.1 新功能的发布&#xff0c;我们更新了编辑器、文档生成器和插件的 API&#xff0c;并添加了 Office API 板块。阅读下文了解详情。 ​ ONLYOFFICE 文档是什么 ONLYOFFICE 文档是一个功能强大的文档编辑器&#xff0c;支持处理文本文档、电子表格、演示文稿、可填写…

探索ChatGPT在程序员日常工作的多种应用

引言 在现代科技迅猛发展的今天&#xff0c;人工智能的应用已经深入到我们生活和工作的各个方面。作为程序员&#xff0c;我们时常面临大量繁杂的任务&#xff0c;从代码编写、错误调试到项目管理和团队协作&#xff0c;每一项都需要花费大量的时间和精力。近年来&#xff0c;…

算法与数据结构——时间复杂度详解与示例(C#,C++)

文章目录 1. 算法与数据结构概述2. 时间复杂度基本概念3. 时间复杂度分析方法4. 不同数据结构的时间复杂度示例5. 如何通过算法优化来提高时间复杂度6. C#中的时间复杂度示例7. 总结 算法与数据结构是计算机科学的核心&#xff0c;它们共同决定了程序的性能和效率。在实际开发中…

大模型产品的“命名经济学”:名字越简单,产品越火爆?

文 | 智能相对论 作者 | 陈泊丞 古人云&#xff1a;赐子千金&#xff0c;不如教子一艺&#xff1b;教子一艺&#xff0c;不如赐子一名。 命名之妙&#xff0c;玄之又玄。 早两年&#xff0c;大模型爆火&#xff0c;本土厂商在大模型产品命名上可谓下足了功夫&#xff0c;引…

C#+uni-app医院HIS预约挂号系统源码 看病挂号快人一步

​​​​​​​ 提到去大型医院机构就诊时&#xff0c;许多人都感到恐惧。有些人一旦走进医院的门诊大厅&#xff0c;就感到迷茫&#xff0c;既无法理解导医台医生的建议&#xff0c;也找不到应该去哪个科室进行检查。实际上&#xff0c;就医也是一门学问&#xff0c;如何优化…

【CS.DS】数据结构 —— 图:深入了解三种表示方法之邻接表(Adjacency List)

文章目录 1 概念2 无向图的邻接表2.1 示例2.2 Mermaid 图示例2.3 C实现2.3.1 简单实现2.3.2 优化封装 2.4 总结 3 有向图的邻接表3.1 示例3.2 C实现3.3 总结 4 邻接图的遍历5 拓展补充References 数据结构 1 概念 优点&#xff1a;空间效率高&#xff0c;适合稀疏图。动态性强…

Win10,Win11电脑重装系统怎么操作,简单一步搞定【保姆级教程】

电脑重装系统怎么操作&#xff1f;电脑使用时间长了&#xff0c;就会出现系统崩溃、病毒感染或者是系统文件损坏等问题。这个时候我们就可以对电脑进行系统重装&#xff0c;也就是恢复电脑出厂设置。现在市面上有很多系统重装工具可以帮助我们解决难题&#xff0c;如果您是电脑…

自定义 Django 管理界面中的多对多内联模型

1. 问题背景 在 Django 管理界面中&#xff0c;用户可以使用内联模型来管理一对多的关系。但是&#xff0c;当一对多关系是多对多时&#xff0c;Django 提供的默认内联模型可能并不适合。例如&#xff0c;如果存在一个产品模型和一个发票模型&#xff0c;并且产品和发票之间是…

Java文件操作小项目-带GUI界面统计文件夹内文件类型及大小

引言 在Java编程中&#xff0c;文件操作是一项基本且常见的任务。我们经常需要处理文件和文件夹&#xff0c;例如读取、写入、删除文件&#xff0c;或者遍历文件夹中的文件等。本文将介绍如何使用Java的File类和相关API来统计一个文件夹中不同类型文件的数量和大小。 准备工作…

数据分析python基础实战分析

数据分析python基础实战分析 安装python&#xff0c;建议安装Anaconda 【Anaconda下载链接】https://repo.anaconda.com/archive/ 记得勾选上这个框框 安装完后&#xff0c;然后把这两个框框给取消掉再点完成 在电脑搜索框输入"Jupyter"&#xff0c;牛马启动&am…

Vitis Accelerated Libraries 学习笔记--OpenCV 安装指南

目录 1. 简介 2. 安装过程 2.1 安装准备 2.2 编译并安装 XRT 2.2.1 下载 XRT 源码 2.2.2 安装依赖项 2.2.3 构建 XRT 2.2.4 打包 DEB 2.2.5 安装 XRT 2.3 编译并安装 OpenCV 2.3.1 下载 OpenCV 源码 2.3.2 创建目录 2.3.3 设置环境变量 2.3.4 构建 opencv 3. 总…

【STM32】看门狗

1.看门狗简介 看门狗起始就是一个定时器&#xff0c;从功能上说它可以让微控制器在程序发生意外&#xff08;程序进入死循环或跑飞&#xff09;的时候&#xff0c;能重新恢复到系统刚上电状态&#xff0c;以保障系统出问题的时候可以重启一次。说的简单一点&#xff0c;看门狗…

加速业务布局,30年老将加盟ATFX,掌舵运营新篇章

全球领先的差价合约经纪商ATFX日前宣布了一项重大人事任命&#xff0c;聘请业界资深人士约翰博格(John Bogue)为机构业务运营总监。约翰博格是一名行业老将&#xff0c;曾在差价合约界深耕三十余载。伴随其加入ATFX&#xff0c;相信他的深厚专业知识和从业经验将为ATFX机构业务…

HarmonyOS NEXT Developer Beta1配套相关说明

一、版本概述 2024华为开发者大会&#xff0c;HarmonyOS NEXT终于在万千开发者的期待下从幕后走向台前。 HarmonyOS NEXT采用全新升级的系统架构&#xff0c;贯穿HarmonyOS全场景体验的底层优化&#xff0c;系统更流畅&#xff0c;隐私安全能力更强大&#xff0c;将给您带来更高…

数据集的未来:如何利用亮数据浏览器提升数据采集效率

目录 一、跨境电商的瓶颈1、技术门槛2、语言与文化差异3、网络稳定性4、验证码处理和自动识别5、数据安全6、法规和合规 二、跨境电商现在是一个合适的商机吗&#xff1f;三、数据集与亮数据浏览器1、市场分析2、价格监控3、产品开发4、供应链优化5、客户分析 四、亮数据浏览器…

Jenkins流水线发布,一篇就解决你的所有疑惑

这次搭建的项目比较常规,前端是react写的,后端是springboot,并且由于是全栈开发,所以是在同一个项目中。接下来我演示下怎么用jenkins进行自动化发布。 1.jenkins必装插件 这里用到的是jenkinsFile主要是基于Groovy这个沙盒,有些前置插件。这里使用maven进行打包,所以需…

如何提高项目风险的处理效率?5个重点

提高项目风险的处理效率&#xff0c;有助于迅速识别和应对风险&#xff0c;减少风险导致的延误&#xff0c;降低成本&#xff0c;提升项目质量&#xff0c;确保项目按时交付。如果项目风险处理效率较低&#xff0c;未能及时发现和处理风险&#xff0c;导致问题累积&#xff0c;…

浏览器扩展V3开发系列之 chrome.runtime 的用法和案例

【作者主页】&#xff1a;小鱼神1024 【擅长领域】&#xff1a;JS逆向、小程序逆向、AST还原、验证码突防、Python开发、浏览器插件开发、React前端开发、NestJS后端开发等等 chrome.runtime API 提供了一系列的方法和事件&#xff0c;可以通过它来管理和维护 Chrome 扩展的生命…

揭示优化Prompt的秘诀:如何让API表现媲美网页版

为什么用GPT API&#xff08;GPT-3.5-turbo&#xff09;进行程序分析时&#xff0c;效果好像比网页版的GPT-3.5差一点&#xff1f;这可能有几个原因&#xff0c;咱们细说一下。 1. Prompt不同 这是最常见的问题之一。API调用时的指令&#xff08;prompt&#xff09;往往比较简…