Reputation: 448
I have application in Kotlin, Spring boot Microservices architecture. I am using a method to accept ByteArray in the API that take zip as ByteArray and inside the zip there will be documents available. I extract that zip to get documents from it (with nested directory structure as well). we are using following library to perform zip extraction
net.lingala.zip4j:zip4j:2.1.2
mostly all the files are extracted fine but with some Zip files we face issue
java.util.zip.ZipException: only DEFLATED entries can have EXT descriptor
Note we have used
commons-io-2.14.0
library to for extracting the file name in the below code snippet.
Also note I have tried upgrading the lingala.zip4j to latest version if this compression method is supported.
Here is the code snippet for reference
fun extractZipFromBase64(zip: ByteArray, ndId: String) {
val requestData = repository.findOneById(ndId) ?: throw Exception("no records found.")
requestData?.let { nummer ->
val detailsData = processRequestClient.getDetails(nummer)
val zis = ZipInputStream(zip.inputStream())
try {
var zipEntry: ZipEntry?
while ((zis.nextEntry.also { zipEntry = it }) != null) {
if (zipEntry?.isDirectory == true) {
logger.info { "Processing file: ${zipEntry?.name} for $ndId" }
} else {
extracteFileFromZip(zipEntry, zis, nummer, detailsData)
}
}
} catch (e: Exception) {
logger.error(e) { "Error occurred while performing upload from zip to data for ndId: $ndId" }
throw Exception("Error occurred while performing upload from zip to data for ndId: $ndId")
} finally {
zis.close()
}
} ?: throw Exception("no records found: $ndId")
}
private fun extracteFileFromZip(
zipEntry: ZipEntry?,
zis: ZipInputStream,
akteZip: Boolean,
nummer: String,
dataRest: DataRest
) {
logger.info { "File Name: ${zipEntry?.name}" }
val bos = ByteArrayOutputStream()
try {
val buffer = ByteArray(1024)
var bytesRead: Int
while ((zis.read(buffer).also { bytesRead = it }) != -1) {
bos.write(buffer, 0, bytesRead)
}
val blob = bos.toByteArray()
val contentType = getMimeTypeFromExtension(zipEntry?.name!!)
saveDocument(nummer, zipEntry, contentType, blob, dataRest)
} catch (e: Exception) {
logger.error(e) { "Error occurred extracteFileFromZip file: ${zipEntry?.name}" }
throw Exception("Error occurred while fetching file: ${zipEntry?.name}")
} finally {
bos.close()
}
}
private fun saveDocument(
nummer: String,
zipEntry: ZipEntry?,
contentType: String,
blob: ByteArray,
dataRest: DataRest) {
//internal logic to save blob - byteArray data
}
private fun getMimeTypeFromExtension(relativePath: String): String {
val extension = FilenameUtils.getExtension(relativePath).lowercase(Locale.getDefault())
return when (extension) {
"pdf" -> MediaType.APPLICATION_PDF_VALUE
"png" -> MediaType.IMAGE_PNG_VALUE
"jpg" -> MediaType.IMAGE_JPEG_VALUE
"jpeg" -> MediaType.IMAGE_JPEG_VALUE
"doc" -> "application/msword"
"docx" -> "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
"xml" -> MediaType.APPLICATION_XML_VALUE
"eml" -> "message/rfc822"
"xlsx" -> "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
"txt" -> MediaType.TEXT_PLAIN_VALUE
else -> MediaType.APPLICATION_OCTET_STREAM_VALUE
}
}
How to fix the compression issue and how to give support for multiple compression methods using this library? Or is it possible to extract the files without facing such errors
Note we have used
commons-io-2.14.0
library to for extracting the file name in the below code snippet.
Also note I have tried upgrading the lingala.zip4j to latest version if this compression method is supported.
How to fix the compression issue and how to give support for muliple compression methods using this library? Or is it possible to extract the files without facing such errors
Upvotes: 0
Views: 35
Reputation: 111
Instead of ZipInputStream
, which only supports DEFLATED
files, try using ZipFile
from lingala.zip4j
, which supports multiple compression algorithms.
Before:
val zis = ZipInputStream(zip.inputStream())
After:
val zipFile = ZipFile(File(outputFile))
zipFile.fileHeaders.forEach { fileHeader ->
if (!fileHeader.isDirectory) {
val extractedFile = zipFile.getInputStream(fileHeader).readBytes()
saveDocument(nummer, fileHeader.fileName, getMimeTypeFromExtension(fileHeader.fileName), extractedFile, dataRest)
}
}
Upvotes: 0