miércoles, 7 de agosto de 2019

GENERATE FILE FROM ARRAY BYTE USING JAVA SPRING JDBC

En el proyecto de java ubicamos nuestra clase DAOImplement para obtener los datos del documento a generar a través de un array de byte.

DocumentoAdjuntoDataImplement.java

@Repository("documentoAdjuntoData")
public class DocumentoAdjuntoDataImplement implements DocumentoAdjuntoData {

private SimpleJdbcCall getDocumentoAdjunto;

 @Autowired
public void setDataSource(DataSource dataSource) {

       
        this.getDocumentoAdjunto = new SimpleJdbcCall(dataSource)
                .withSchemaName(Constantes.BDContext.Schema)
                .withCatalogName(Constantes.BDContext.PKG_ADMINISTRACION)
                .withProcedureName("USP_GET_DOCUMENADJUNTO")
                .returningResultSet("CV", new DocumentoAdjuntoRowMapper());
       
    }

@Override
    public DocumentoAdjunto get(DocumentoAdjunto item) {
        DocumentoAdjunto doc = new DocumentoAdjunto();
        try {
            SqlParameterSource in = new MapSqlParameterSource()
                    .addValue("V_NOMDOC", item.getNOMDOC());
           Map<String, Object> out = getDocumentoAdjunto.execute(in);
           List<DocumentoAdjunto> result = (List<DocumentoAdjunto>) out.get("CV");
           return result.get(0);

        } catch (Exception e) {
            System.out.println(e);
        }
        return doc;
    }

private static class DocumentoAdjuntoRowMapper implements RowMapper<DocumentoAdjunto> {
        @Override
        public DocumentoAdjunto mapRow(ResultSet resultSet, int rowNum) throws SQLException {
            DocumentoAdjunto doc = new DocumentoAdjunto();
            doc.setIDDOCUMENT(resultSet.getInt(("IDDOCUMENT")));
            doc.setNOMDOC(resultSet.getString("NOMDOC"));
            doc.setDESCDOC(resultSet.getString("DESCDOC"));
            doc.setURLDOC(resultSet.getString("URLDOC"));
            doc.setFeccreacio(resultSet.getString("FECCREACIO"));
            doc.setUsucreacio(resultSet.getString("USUCREACIO"));
            doc.setDESCPROCACTUAL(resultSet.getString("VALOR"));
            doc.setPROCACTUAL(resultSet.getInt("PROCACTUAL"));

            Blob blob = resultSet.getBlob("ARCHIVO");
            byte[] bytes = blob.getBytes(1, (int) blob.length());
            doc.setByteDOC(bytes);
            return doc;
        }
    }



En esta clase observamos que en el constructor setDataSource instancia la conexión a la base de datos declarando al StoredProcedure con su respectivo esquema y paquete, asimismo se declara un resultset que invocará a la función DocumentoAdjuntoRowMapper que se va disparar cuando se obtenga los resultado del execute. Es importante resaltar que dentro de la clase RowMapper se hace la conversión del BLOB a un array de byte[], para la creación del archivo mas adelante.


Luego, tenemos una clase controller llamado FileDownloadController.java  que tiene una función de tipo POST que realiza la descarga mediante la url .../file/{nombreArchivo} tal como se declara en el @RequestMapping.

@Controller
@RequestMapping("/download")
public class FileDownloadController {

    @Autowired
    ParametroValorService parametroValorService;
    @Autowired
    DocumentoAdjuntoService  _DocumentoAdjuntoService;

@RequestMapping("/file/{fileName:.+}")
    public void downloadPDFResource(HttpServletRequest request,
            HttpServletResponse response,
            @PathVariable("fileName") String fileName) {
       
        List<ParametroValor> lstResult = parametroValorService.list(Constantes.Parametros.URL);
        for (ParametroValor oItem : lstResult) {
            
            //OBTENEMOS EL ARREGLO DE BYTE COMO ATRIBUTO DEL OBJETO DocumentoAdjunto
            DocumentoAdjunto item = new DocumentoAdjunto();
            item.setNOMDOC(fileName);
            item = _DocumentoAdjuntoService.getDocumento(item);
            
            //GENERAMOS EL DOCUMENTO DESDE ARRAY BYTE
            String urlWriteFile = System.getProperty("user.home");
            urlWriteFile += File.separator + oItem.getValor() +File.separator + fileName;
            Util.writeBytesToFile(item.getByteDOC(), urlWriteFile);
            Path pathfileOrigen = Paths.get(urlWriteFile);
            
            //DESCARGAMOS EL ARCHIVO SEGUN LA EXTENSION    
            File newfile = new File(urlWriteFile);
            String extension = Util.getFileExtension(newfile);
            switch (extension) {
                case "doc":
                    response.setContentType("application/msword");
                    break;
                case "docx":
                    response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
                    break;
                default:
                    response.setContentType("application/"+extension+"");
                    break;
            }
            response.setHeader("Content-Disposition","attachment;filename="+newfile.getName());
         
            try {
                Files.copy(pathfileOrigen, response.getOutputStream());
                response.getOutputStream().flush();
                Util.deleteFile(urlWriteFile);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
           
        }

    }
}


En esta clase observamos los siguientes parámetros:
lstResult: Obtener un parámetro de la base de datos para utilizar como nombre del archivo donde pondremos documentos de forma temporal. 
item: Objeto que filtra los datos del documento mediante el nombre del archivo y a la vez devuelve el arreglo de bytes desde la base de datos.
urlWriteFile: Se genera una ruta especifica donde se van alojar los archivos, ya sea en windows o linux, al fin a cabo será de forma temporal. Por ejemplo para linux genera una ruta "/home/oracle/[lstResult]/[item.filename]".
writeBytesToFile: La función que genera el documento:
public static void writeBytesToFile(byte[] bFile, String fileDest) {
        try (FileOutputStream fileOuputStream = new FileOutputStream(fileDest)) {
            fileOuputStream.write(bFile);
        } catch (IOException e) {
            e.printStackTrace();
        }


    }
response.setContentType: Tipo de extensión del archivo a descargar.
deleteFile: Función que elimina el archivo una vez descargado:
public static void deleteFile(String urlFile) throws IOException{
        
        try
        { 
            Files.deleteIfExists(Paths.get(urlFile)); 
        } 
        catch(NoSuchFileException e) 
        { 
            System.out.println("No such file/directory exists"); 
        } 
        catch(DirectoryNotEmptyException e) 
        { 
            System.out.println("Directory is not empty."); 
        } 
        catch(IOException e) 
        { 
            System.out.println("Invalid permissions."); 
        } 

    }
getFileExtension: Función que devuelve la extensión de un documento:
public static String getFileExtension(File file) {
        String fileName = file.getName();
        if(fileName.lastIndexOf(".") != -1 && fileName.lastIndexOf(".") != 0)
        return fileName.substring(fileName.lastIndexOf(".")+1);
        else return "";

    }



No hay comentarios:

Publicar un comentario