viernes, 20 de abril de 2018

Crear ZIP Con Archivo CSV Dentro, A Partir De XML y Obtener Su Base64 - Java


Hoy en día existen muchos sistemas legados que en sus payloads de entrada precisan que se les pase como parametro de entrada un string Base64 pero no de un contenido en particular... sino mas bien de un archivo ZIP que contendra de 1 a N archivos CSV dentro.

En este articulo se presenta una potencial clase Java que hace todo esto.


Clase Java

Como parametro de entrada a la clase Java, se le pasa un XML como string. Esto permite mas flexibilidad para trabajarlo desde OSB o BPEL.


ZipUtil.java

package com.soajp.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.ZipOutputStream;
import java.util.zip.ZipEntry;
import java.io.InputStream;
import java.io.StringReader;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.bind.DatatypeConverter;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

/**
 *
 * @author Juan Lozano Pizarro
 */

public class ZipUtil {

    public static String compressData(String xmlAsString) {
        // parsing entities to special character
        xmlAsString = xmlAsString.replaceAll("&lt;", "<");
        xmlAsString = xmlAsString.replaceAll("&gt;", ">");

        // Remove XML header
        xmlAsString = xmlAsString.indexOf("?>") > -1 ? xmlAsString.substring(xmlAsString.indexOf("?>") + 2) : xmlAsString;
      
        // Remove Comment
        xmlAsString = xmlAsString.indexOf("-->") > -1 ? xmlAsString.substring(xmlAsString.indexOf("-->") + 3) : xmlAsString;
      
        // Fix line break
        xmlAsString = xmlAsString.substring(xmlAsString.indexOf("<"));

        // assign current namespace to a variable
        String ns;
        if(xmlAsString.indexOf(":zipFile") > -1) {
            // have namespace
            ns = xmlAsString.substring(xmlAsString.indexOf("<") + 1, xmlAsString.indexOf(":"));
        } else {
            // not have namespace
            ns = "";
        }
       
        xmlAsString = xmlAsString.replaceAll(ns + ":", "");
       
        String stringDate = new SimpleDateFormat("yyyy/MM/dd").format(new Date());
       
        // build the XML
        Document doc;
        try {
            doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new StringReader(xmlAsString)));
        } catch (ParserConfigurationException | SAXException | IOException ex) {
            Logger.getLogger(ZipUtil.class.getName()).log(Level.SEVERE, null, ex);
            return "";
        }
        NodeList lineArray = doc.getElementsByTagName("line");
       
        String content = "";
        if (
lineArray.getLength() > 0) {
            Element header = (Element)
lineArray.item(0);
                content = content +
                          header.getElementsByTagName("dato1")
                            .item(0).getTextContent() + "|" +
                          header.getElementsByTagName("dato2")
                            .item(0).getTextContent() + "|" +
                          header.getElementsByTagName("dato3")
                            .item(0).getTextContent() + "|" +
                          header.getElementsByTagName("dato4")
                            .item(0).getTextContent() + "|" +
                          header.getElementsByTagName("dato5")
                            .item(0).getTextContent() + "|" +
                          header.getElementsByTagName("dato6")
                            .item(0).getTextContent() + "\n";

            for (int i=1; i <
lineArray.getLength(); i++) {
                Element line= (Element)
lineArray.item(i);
                content = content +
                         
line.getElementsByTagName("dato1")
                            .item(0).getTextContent() + "|" +
                         
line.getElementsByTagName("dato2")
                            .item(0).getTextContent() + "|" +
                         
line.getElementsByTagName("dato3")
                            .item(0).getTextContent() + "|" +
                         
line.getElementsByTagName("dato4")
                            .item(0).getTextContent() + "|" +
                          stringDate + "|" +
                         
line.getElementsByTagName("dato5")
                            .item(0).getTextContent() + "|" +
                         
line.getElementsByTagName("dato6")
                            .item(0).getTextContent() + "\n";
            }
            content = content.trim();
        }
       
        // convert CSV file to Base64
        byte[] contentBytes = content.getBytes();
        String encodedString = DatatypeConverter.printBase64Binary(contentBytes);

        // starting compress process
        byte[] buffer = new byte[1024];

        try {
            byte[] rbytes = DatatypeConverter.parseBase64Binary(encodedString); 
           
            ByteArrayOutputStream ostream = new ByteArrayOutputStream(rbytes.length);
            ZipOutputStream zos = new ZipOutputStream(ostream);
            ZipEntry ze = new ZipEntry("Worker.dat");
            zos.putNextEntry(ze);
           
            InputStream is = new ByteArrayInputStream(rbytes);

            int len;
            while ((len = is.read(buffer)) > 0) {
                zos.write(buffer, 0, len);
            }

            is.close();
            zos.closeEntry();

            //remember close it
            zos.close();

            String encodeString = DatatypeConverter.printBase64Binary(ostream.toByteArray());
            return encodeString;
        } catch (IOException ex) {
            Logger.getLogger(Zip.class.getName()).log(Level.SEVERE, null, ex);
            return "";
        }
    }
}



El XML que se le pasa como parametro a la clase Java es el siguiente:

<zipFile>
            <line>
                        <dato1>Header1</dato1>
                        <dato2>Header2</dato2>
                        <dato3>Header3</dato3>
                        <dato4>Header4</dato4>
                        <dato5>Header5</dato5>
                        <dato6>Header6</dato6>
            </line>
            <line>
                        <dato1>Dato1</dato1>
                        <dato2>Dato2</dato2>
                        <dato3>Dato3</dato3>
                        <dato4>Dato4</dato4>
                        <dato5>Dato5</dato5>
                        <dato6>Dato6</dato6>
            </line>
</zipFile>




Como resultado de ejecutar la clase se obtiene el Base64 del archivo ZIP.

Cualquier duda o mejora del codigo puede debatirse con libertad y respeto en los comentarios de este articulo.

No hay comentarios:

Publicar un comentario