0

I am trying to show pdf document in a iframe. I have set the source of the iframe to a servlet and passing some parameter to the servlet.

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    try {
        String docName = request.getParameter("docName");
        String id = request.getParameter("id");

        if (StringUtils.isNotBlank(id) && StringUtils.isNotBlank(docName)) {
            DocumentService service = DamServiceProvider.PROVIDER.getDocumentService();
            FileInBean fileInBean = new FileInBean();
            fileInBean.setDocName(docName);
            fileInBean.setId(Integer.valueOf(id));
            FileDataBean fileDataBean = service.getFileDataBean(fileInBean);

            if (fileDataBean.getStatusCode() == 0) {
                Map<String, String> headerFieldMap = fileDataBean.getHeaderFieldMap();
                String contentType = headerFieldMap.get("Content-type");
                String contentLength = headerFieldMap.get("Content-Length");
                String contentDisposition = headerFieldMap.get("Content-Disposition");

                byte[] stream = fileDataBean.getStream();
                ByteArrayInputStream inputStream = new ByteArrayInputStream(stream);
                OutputStream outputStream = response.getOutputStream();

                response.reset();
                response.setBufferSize(4096);
                response.setContentLength(Integer.valueOf(contentLength));
                response.setContentType(contentType);
                response.setHeader("Content-Disposition", contentDisposition);

                System.out.println(contentDisposition);
                IOUtils.copy(inputStream, outputStream);

                outputStream.close();
                inputStream.close();
            }
        }
    } catch (Exception ex) {
        Log.error(this, ex.getMessage());
    }
}

Now in my page I have a master–detail interface. The master part contains a carousel of series of pdf file items. On clicking the item I am refreshing the detail view which contains the iframe.

I can see the servlet get called. Most of the times the iframe is displaying the pdf document. But sometimes it is showing weird xml structure which contains xml tags and some unreadable output. Please see the attach image:

Screenshot

This is not happening for a particular file. If a file shows this output, sometime later if click the item it shows the valid pdf and if an item shows a valid pdf sometime later it shows this kind of output if I click on it. When the iframe shows this type of output my browser displays an information that this pdf document might be corrupted.

I have checked the repository where the files are and I have found no issues there. All of them are valid pdf and I can download and open them by pdf reader.

I am unable to find the cause of this issue. Any pointer would be very helpful.

Update - 1

I have checked the output. It ends with %%EOF and has %PDF in the beginning.

Update - 2

I have checked in Chrome's Network Console the GET is returning mainly three types of content-type: application/pdf, text/plain, application/octet-stream.

  • application/pdf: it is showing the pdf.
  • text/plain it is showing the content that I mentioned above.
  • application/octet-stream didn't arise in Firefox but in Chrome and in that case it is opening the download file window.

I have placed a log in the servlet to see the content-type that returned from service. For all the cases it is application/pdf.

2 Answers 2

1

I think it maybe a problem with the content-Type, you can confirm if this is the espected in your browser with the developer tools (in the network console for Chrome).

Sign up to request clarification or add additional context in comments.

3 Comments

Hello. I did what you said and found that in chrome the GET is returing three types of content-type: application/pdf, text/plain, application/octet-stream. In case of application/pdf it is showing the pdf. In case of text/plain it is showing the content that I mentioned above. The case application/octet-stream didn't arise in firefox but in chrome and in that case it is opening the download file window. I have placed a log in the servlet to see the content-type that returned from service. All the cases it is application/pdf. Do you have any idea?
I am not sure, only an idea, but can you review Content-Disposition? The value must be attachement or inline (I think you prefer inline) and must include the file name (` httpResponse.setHeader("Content-Disposition", "\"" + getContentDisposition() + "\"" + "; filename=\"" + getFileName() + "\"")); `).
The content disposition is okay. I have checked it.
0

try something like this.

File pdfFile = new File(this.pdfStoreLocation + pdfFileName);
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=" + pdfFileName);
response.setContentLength((int) pdfFile.length());

BufferedInputStream bis = new BufferedInputStream(new FileInputStream(pdfFile));
BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());

// byte array declared
byte[] buf = new byte[2048];
boolean eof = false;
while (!eof) {
    int length = bis.read(buf);
    if (length == -1) {
        eof = true;
    }else {
        bos.write(buf, 0, length);
    }
}

try {
     bis.close();
}catch (IOException ex) {
     LOGGER.error("Exception in closing buffered input stream on pdf file->" +   this.pdfStoreLocation + pdfFileName);
}

try {
     bos.flush();
}catch (IOException ex) {
     LOGGER.error("Exception in fliushing buffered output stream on pdf file->"
                            + this.pdfStoreLocation + pdfFileName);
}
bos.close();

2 Comments

Sorry my friend I can't do this. I don't have any file. What I have is byte array. And you code snippet which copy the two streams is same if I use IOUtils.copy method.
its the same thing. whether you create a byte array from a file or a stream is superficial. the idea is that you need to add content-type headers and disposition before your start streaming the content back. The idea was to demonstrate how it can be done.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.