You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中不落地提取响应Zip文件及损坏问题解决

问题根源

你当前代码的核心错误是使用response1.body().string()读取二进制Zip文件的响应体。string()方法会将响应的字节数据按**字符编码(默认UTF-8)**转换为字符串,这会破坏Zip文件的二进制结构——因为Zip文件包含大量非UTF-8兼容的字节,转换为字符串再转回字节时,部分字节会丢失或被篡改,导致内存中的Zip数据损坏。而直接将原始字节写入文件时,数据是完整的,所以保存后Zip文件正常。

解决方案:内存中直接解析Zip并提取内容

无需将Zip保存为物理文件,直接通过字节流在内存中解析Zip,提取内部文件内容后存入数据库。具体步骤如下:

1. 修改响应读取方式,获取原始字节流

替换string()方法,改用bytes()获取原始二进制数据,或者直接获取ResponseBody的输入流。

2. 使用ZipInputStream解析内存中的Zip数据

通过ZipInputStream遍历Zip内的所有文件,读取每个文件的内容。

3. 将文件内容存入数据库

根据业务需求,将读取到的文件内容(如文本、字节数组等)写入数据库。

修改后的完整代码示例
OkHttpClient client1 = new OkHttpClient().newBuilder()
        .build();
MediaType mediaType1 = MediaType.parse("text/plain");
RequestBody body1 = RequestBody.create(mediaType1, "");
Request request1 = new Request.Builder()
        .url(vers)
        .method("POST", body1)
        .addHeader("Cookie", "ASP.NET_SessionId=44dxexdxass5mtf00udjfwns")
        .build();

try (Response response1 = client1.newCall(request1).execute()) {
    if (!response1.isSuccessful()) {
        throw new IOException("请求失败: " + response1);
    }

    // 获取响应体的输入流(原始二进制数据)
    try (InputStream inputStream = response1.body().byteStream();
         ZipInputStream zipInputStream = new ZipInputStream(inputStream)) {

        ZipEntry zipEntry;
        // 遍历Zip内的每个文件
        while ((zipEntry = zipInputStream.getNextEntry()) != null) {
            if (!zipEntry.isDirectory()) { // 跳过目录,只处理文件
                String fileName = zipEntry.getName();
                System.out.println("正在处理文件: " + fileName);

                // 读取文件内容(根据文件类型选择读取方式,这里以字节数组为例)
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024];
                int len;
                while ((len = zipInputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, len);
                }
                byte[] fileContent = outputStream.toByteArray();

                // 这里将fileContent存入数据库,示例伪代码
                // yourDatabaseService.saveFileContent(fileName, fileContent);
                // 若文件是文本类型,可转换为字符串:new String(fileContent, StandardCharsets.UTF_8)
            }
            // 关闭当前ZipEntry
            zipInputStream.closeEntry();
        }
    }
} catch (IOException e) {
    e.printStackTrace();
}
关键注意事项
  • 必须使用byteStream()或bytes()获取二进制数据,绝对不能用string()处理非文本响应。
  • 所有流资源要通过try-with-resources自动关闭,避免内存泄漏。
  • 如果Zip内有大文件,建议分块读取并写入数据库,避免内存溢出。

内容的提问来源于stack exchange,提问作者FNA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 19:30:41