emphywork
emphywork

Reputation: 448

Facing java.util.zip.ZipException: only DEFLATED entries can have EXT descriptor with Zip extraction with net.lingala.zip4j:zip4j:2.11.5 library

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

Answers (1)

Maksim Banit
Maksim Banit

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

Related Questions