Lea BLOB (contenido PDF) de la base de datos y edite y envíe archivos editados en PDF sin crear un archivo físico

Estoy usando una base de datos Oracle y almacenando contenido PDF en un campo BLOB.

Quiero leer el contenido BLOB y luego editar y generar el contenido editado.

La edición que necesito hacer es:

añada un título sobre el contenido BLOB agregue una marca de agua en cada páginaadd pie de página en cada página

Entonces necesito generar el archivo sin crear ningún archivo físico que esté dentro del flujo de respuesta.

Intenté lograr esto usando itext pero no estaba llegando a ningún lado con él. Estoy atrapado y no estoy seguro de por dónde empezar.

También a veces podría tener que combinar el contenido de blob en uno, pero eso es algo que seguramente sucederá una vez en un millón ... así que eso no es una preocupación ahora ...

¿Cómo puedo cumplir mis requisitos principales de los tres pasos anteriores usando Java? ¿Es posible con Itext? ¿O hay alguna otra biblioteca disponible que ayudaría?

Database: Oracle 10g Release 2

OS: Linux Fedora / Redhat

Front-end: Java / Servlet / JSP

EDITA

Esto es lo que intenté hacer

oracle.sql.BLOB blob = (BLOB) rs.getBlob("MYPDF");
byte[] bytes = blob.getBytes(1, (int) blob.length());
InputStream is = blob.getBinaryStream();
Document document=new Document();
ServletOutputStream servletOutputStream = response.getOutputStream();
PdfWriter writer=PdfWriter.getInstance(document, servletOutputStream);
document.open();
document.add(new Paragraph("Some title"));
document.add(new Paragraph("Some title"));
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=output.pdf");
servletOutputStream.write(bytes, 0, bytes.length);
servletOutputStream.flush();
servletOutputStream.close();
document.close();

El programa genera el contenido pdf en el campo BLOB en la base de datos y sin el título.

y cuando cambio un poco en el código (cambiar el orden de las últimas líneas) a:

document.close();
servletOutputStream.flush();
servletOutputStream.close();

Obtengo el documento con el contenido del título y sin contenido pdf del campo BLOB. Es lo primero que se cierra (servletoutputstream / document) que se lanza como salida.

Y cuando cerré el documento antes de poner el contenido de blob en el flujo de salida:

document.close();
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=output.pdf");
servletOutputStream.write(bytes, 0, bytes.length);
servletOutputStream.flush();
servletOutputStream.close();

Tengo el navegador mostrando algo como esto:

%PDF-1.4 %���� 2 0 obj <>stream x�+�r �26S�00SI�2P�5��1���BҸ4��sSJ2KrR5C��*P�B�5�+��k)&� endstream endobj 4 0 obj <<<>>>/MediaBox[0 0 595 842]>> endobj 1 0 obj <> endobj 3 0 obj <> endobj 5 0 obj <> endobj 6 0 obj <> endobj xref 0 7 0000000000 65535 f 0000000304 00000 n 0000000015 00000 n 0000000392 00000 n 0000000147 00000 n 0000000443 00000 n 0000000488 00000 n trailer <]/Info 6 0 R/Size 7>> startxref 620 %%EOF 

Necesito que el archivo salga con el contenido del pdf y el título también.

Espero que esta edición ayude un poco ...

UPDATE (Archivo arrojado en respuesta con el título y el Contenido BLOB):

Document document = new Document(PageSize.A4, 108, 72, 30, 72);
PdfWriter writer = PdfWriter.getInstance(document, outputstream);

document.open();

///-----Added Some Title----///

rs = stmt.executeQuery(queryToGetBLOBCONTENT);

if (rs.next()) {


response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=watermark.pdf");
oracle.sql.BLOB blob = (BLOB) rs.getBlob("MYPDF");
byte[] bytes = blob.getBytes(1, (int) blob.length());
InputStream is = blob.getBinaryStream();
PdfReader pdfReader = new PdfReader(is, bytes);
BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
PdfContentByte cb = writer.getDirectContent(); // Holds the PDF
PdfImportedPage page;
int currentPageNumber = 0;
int pageOfCurrentReaderPDF = 0;
while (pageOfCurrentReaderPDF < pdfReader.getNumberOfPages()) {
    if (pageOfCurrentReaderPDF > 0) {
        document.newPage();
    }
    pageOfCurrentReaderPDF++;
    currentPageNumber++;
    page = writer.getImportedPage(pdfReader, pageOfCurrentReaderPDF);
    cb.addTemplate(page, 0, 0);
}
pageOfCurrentReaderPDF = 0;
outputstream.flush();
document.close();
outputstream.close();

}

Esto me da un archivo en respuesta que tiene un BLOB de DB con el título en la parte superior y que se realiza sin generar ningún archivo físico.

Ahora para generar la marca de agua y necesito pasar el documento al PDfreader, ¿cómo puedo lograrlo antes de cerrar el documento (es decir, ejecutardocument.close(), que pondría el archivo sin marca de agua cuando se cerró el flujo)

¿Qué estoy haciendo mal en este código? ¿Cómo puedo lograr el mismo archivo con la marca de agua y eso también sin crear un archivo en el fondo?

Respuestas a la pregunta(2)

Su respuesta a la pregunta