Как обработать zip-файл multipart / form-data в aws lambda Rest api - PullRequest
0 голосов
/ 11 января 2020

У меня есть лямбда, написанная на java8. Эта лямбда интегрирована со шлюзом API, так что я могу отправить запрос POST с multipart / form-data. Я использовал почтальон для проверки моего API, с ключом тела данных формы «file».

У меня есть 2 вопроса (я разделю на другой вопрос, если это не разрешено):

  • Как я могу получить имя файла расположения контента? Мой код кажется таким отвратительным, потому что расположение содержимого в строке. Есть ли лучший способ?

String header = multipartStream.readHeaders ();

  • Внутри zip-файла есть еще один zip-файл внутри ( не мой выбор) Когда я распаковываю, он не получает все файлы. Как я могу также автоматически разархивировать с детьми?

Вот мой код

public class ProcessFileService implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
     public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent event, Context context) {
    //Create the logger
    LambdaLogger logger = context.getLogger();
    APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent();

    //Set up contentType String
    String contentType = "";

    try {
        //Get the uploaded file and decode from base64
        byte[] bI = Base64.decodeBase64(event.getBody().getBytes());

        //Get the content-type header and extract the boundary
        Map<String, String> headers = event.getHeaders();

        if (headers != null) {
            contentType = headers.get("Content-Type");
            logger.log("Content type " + contentType);
        }

        String[] boundaryArray = contentType.split("=");

        //Transform the boundary to a byte array
        byte[] boundary = boundaryArray[1].getBytes();

        //Create a ByteArrayInputStream
        ByteArrayInputStream content = new ByteArrayInputStream(bI);

        //Create a MultipartStream to process the form-data

        MultipartStream multipartStream = new MultipartStream(content, boundary, bI.length, null);

        //Create a ByteArrayOutputStream
        ByteArrayOutputStream out = new ByteArrayOutputStream();

        //Find first boundary in the MultipartStream
        boolean nextPart = multipartStream.skipPreamble();

        //Loop through each segment
        while (nextPart) {
            //This header contains content-disposition
            String header = multipartStream.readHeaders();

            logger.log("Headers:");

            logger.log("Content disposition: " + header);

            //Write out the file to our ByteArrayOutputStream
            multipartStream.readBodyData(out);
            //Get the next part, if any
            nextPart = multipartStream.readBoundary();
        }

        //Log completion of MultipartStream processing
        logger.log("Data written to ByteStream");

        //Prepare an InputStream from the ByteArrayOutputStream
        InputStream fis = new ByteArrayInputStream(out.toByteArray());
        File destDir = new File("unzipTest");
        destDir.mkdir();
        byte[] buffer = new byte[bI.length];

        logger.log("destination file exists " + destDir.exists());

        ZipInputStream zis = new ZipInputStream(fis);
        ZipEntry zipEntry = zis.getNextEntry();
        while (zipEntry != null) {
            File newFile = newFile(destDir, zipEntry);
            FileOutputStream fos = new FileOutputStream(newFile);
            int len;
            while ((len = zis.read(buffer)) > 0) {
                fos.write(buffer, 0, len);
            }

            logger.log("file " + newFile.getName());
            fos.close();
            zipEntry = zis.getNextEntry();
        }
        zis.closeEntry();
        zis.close();

        logger.log("File count : " + destDir.listFiles().length);
        logger.log("Name: " + destDir.listFiles()[0].getName());

        destDir.delete();

        //Provide a response
        response.setStatusCode(200);
        Map<String, String> responseBody = new HashMap<String, String>();
        responseBody.put("Status", "File stored in S3");
        String responseBodyString = new JSONObject(responseBody).toJSONString();
        response.setBody(responseBodyString);

    }
    catch (IOException e) {
        // Handle MultipartStream class IOException
        response.setStatusCode(500);
        Map<String, String> responseBody = new HashMap<String, String>();
        responseBody.put("Status", "oops");
        String responseBodyString = new JSONObject(responseBody).toJSONString();
        response.setBody(responseBodyString);
        logger.log(e.getMessage());
    }

    logger.log(response.toString());
    return response;
}

public static File newFile(File destinationDir, ZipEntry zipEntry) throws IOException {
    File destFile = new File(destinationDir, zipEntry.getName());

    String destDirPath = destinationDir.getCanonicalPath();
    String destFilePath = destFile.getCanonicalPath();

    if (!destFilePath.startsWith(destDirPath + File.separator)) {
        throw new IOException("Entry is outside of the target dir: " + zipEntry.getName());
    }

    return destFile;
}
...