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
相关产品推荐
相关产品推荐

