Question

On IBM Domino Server (version 8.5.3FP1 on Win32 platform) there are two web-agents, to generate PDF and RTF files by request.

Every agent generates RTF or PDF file in a temporary folder, then opens OutputStream instance to write this file to the client (browser, when save-file dialog appears).

All things work ok. Files are generated and saved correctly in temporary folder. But writing these files to OutputStream to let a user save it to the local disk, it does not work properly. Some files were written ok (small files, ~11Kb), but bigger files, ~34K were saved partially (sometimes 276 bytes saved, sometimes 4K bytes saved, etc).

I get OutputStream in my agents as follows:

final OutputStream os = this.getAgentOutputStream();

When file is generated and saved I use:

final FileInputStream fis = new FileInputStream(pdfFilePath);
IOUtils.copy(fis, os); // it is from Apache Commons IOUtils
fis.close();

Does not work.

Then I used this way instead:

final byte[] resultArray = FileUtils.readFileToByteArray(new File(pdfFilePath)); // result array has correct length and correct contents
os.write(resultArray);
os.flush();
os.close();

Does not work.

Then I used this way instead (tricky, but just for experimental purposes):

final byte[] resultArray = FileUtils.readFileToByteArray(new File(pdfFilePath)); // result array has correct length and correct contents
for (byte a:resultArray) {
    os.write(a);
}       

os.flush();
os.close();

Does. not. work.

Before sending data to output stream I have invoked:

java.io.PrintWriter pw = this.getAgentOutput();
pw.println("Content-type: application/pdf"); // also tried octet-stream, no effect
pw.println("Content-Disposition: attachment; filename=\"file.pdf\"");

And my question is as follows, folks. What is wrong with my approach? What I am doing wrong here? File is created and saved on server correctly. Output stream opened correctly, file read correctly. When I write to output stream there's no exception. Output stream flushed and closed correctly.

What is wrong? I am trying to solve this the whole day, but I did not find a clue.

Any ideas?

Was it helpful?

Solution

Seems that Domino has bug with agent OutputStream. Stream obtained via agentRef.getAgentOutputStream(); does not work properly and performs partial write.

Instead of using this way I decided to attach files to a NotesDocument instance, save it and provide user with link to attached files in this document.

OTHER TIPS

This frustrated me too, but fortunately I was able to figure out an alternative approach.

https://www.linkedin.com/pulse/writing-binary-data-from-notes-agent-arun-shankar

Step 1: Convert the Byte Array as JSON Array String.

Write a loop to create a JSON Array String with the Byte Array.

    byte[] pdfFile = pdf.getPDF();

ByteBuffer byteBuffer = ByteBuffer.wrap(pdfFile);

CharBuffer result =  Charset.forName("UTF-8").decode(byteBuffer);



PrintWriter agentPrintWriter = getAgentOutput();

agentPrintWriter.println("Content-type:application/pdf");

agentPrintWriter.println("Content-Disposition:attachment;filename=\"Report.pdf\"\n");



StringBuilder buffer = new StringBuilder();

buffer.append("[");

      for(int index=0;index<pdfFile.length;index++)

      {

            buffer.append(""+pdfFile[index]);

            if(index<pdfFile.length-1)

                  buffer.append(",");

      }

      buffer.append("]");



agentPrintWriter.println(buffer.toString());

The above should produce a String representing a JSON array like the one below.

“[37,80,68,70,45,49,46,52,10,49,32,48,32,111,98,106,10,60,60,….,10]”

Write this string using the PrintWriter instance of the agent.

Step 2: Create a Blob with the Received Data and Open it was Attachment

The Data received on the Client side would be a JSON String. This can be converted to a Byte Array and downloaded as an Attachment by creating Blob object from it.

//Data Received from the AJAX Request

var byteArray = new Uint8Array(JSON.parse(data));

var blob = new Blob([byteArray], {type: "application/pdf"});

var blobUrl = URL.createObjectURL(blob);

window.open(blobUrl)

I tested the solution only in Google Chrome, though I am pretty sure, it would work on other browsers as well.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top