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