views:

345

answers:

4

I am using a JSP to display a single TIFF file. The flow is as follows:

  1. I am given a PDF to convert to a TIFF.
  2. I feed a 'black box' API the PDF in the form of a File object and an OutputStream (I am currently using a ByteArrayOutputStream but that can change as needed.
  3. The 'black box' converts the PDF to a TIFF and saves the result to the OutputStream.
  4. I use out.println(outputstream) to spit out the TIFF.

The problem is that I am getting a text stream instead of a displayed image. I have used the following head/meta tag:

    <head><title>PDF to TIFF tester</title>
  <META HTTP-EQUIV="Content-Script-Type" CONTENT="image/tiff"></head>
  <body>

But that does not change the end result. Any help?

A: 

This wont work. You need to the content type of http response to image/tiff.

Fore more info: http://www.apl.jhu.edu/~hall/java/Servlet-Tutorial/Servlet-Tutorial-Response-Headers.html

Midhat
This is an entirely different setup to what I am handling, though. A JSP and a Servlet are two entirely different things. I cannot use the response object with inline code on a JSP. Is there another way to set the response type?
YYY
like someone said, use a servlet
Midhat
A: 

The meta tag isn't what the browser looks at. Try using a scriptlet to set the content type on the response object. This page has some suggestions.

sblundy
+2  A: 

You shouldn't use JSP for this. It's a view technology providing a textbased template to put HTML/CSS/JS code in and facilities to interact with backend Java code with help of taglibs (JSTL and so on) and EL (Expression Language, the ${} things).

A TIFF image isn't character (text) data. It's a binary data. You really need to use a servlet for this. You shouldn't use Writer methods to return binary data. You should use OutputStream methods for this. Otherwise the binary data would get corrupted (that's also what happens in a JSP since it under the hoods uses a Writer).

Here's a kickoff example how your servlet should look like:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String pdfFilename = request.getParameter("filename");
    File pdfFile = new File("/path/to/all/pdf/files", pdfFilename);

    response.setHeader("Content-Type", "image/tiff");
    doYourThingToConvertPdfFileToTiff(pdfFile, response.getOutputStream());
}

Map this servlet on an url-pattern of for example /pdf2tiff so that you can invoke it by http://example.com/contextname/pdf2tiff?filename=file.pdf in links or browser address bar or even in src attribute of an <img> element.

The doYourThingToConvertPdfFileToTiff is your "black box" API which seems to already write the TIFF to the given OutputStream. Just make use of it and pass the one of the HTTP response through.


Update: If you really, really need to use JSP for this, you could just write the same code in JSP as you would do in a Servlet class. You can practically copypaste it. Only ensure that you are not writinig any template text to the stream, this includes linebreaks and whitespace outside the scriptlets. Otherwise it would get written to the binary file as well and corrupt it.

If you have multiple scriptlet blocks, then you need to arrange them so that there's no linebreak between the ending %> of a scriptlet and the starting <% of the next scriptlet. Thus, e.g.

<%@page import="java.io.File" %><%
    //...
%>

instead of

<%@page import="java.io.File" %>
<%
    //...
%>
BalusC
I'd love to use a Servlet for this, but my co-workers have been rather adamant that I shouldn't be. The decision to use a JSP was not my own.Incidentally, I found the way to handle the encoding from the first line of the JSP; <%@ page language="java" contentType="image/tiff; charset=UTF-8" pageEncoding="TIFF" %>However, that causes the project to complain that it is not supported, which is something I was a little fearful of seeing the whole time. I think this question might be closed while I take these findings to my co-workers.
YYY
Updated answer. I by the way hope that you got insight what you actually should do with the `OutputStream`. Don't pass an `ByteArrayOutputStream` which you massage back into an `InputStream` later to write it to the `OutputStream` of the response. That's only plain inefficient. You also really cannot `print()` the `OutputStream` instance, you would only see the outcome of `Object#toString()` in the response.
BalusC
This is absolutely the best way to do this, it can stream the PDF to the client as it is rasterized (if your black box supports it). This can save memory. Though make sure to check if your black box does rasterization on the fly, especially if you have high numbers of concurrent requests.
Justin
A: 

If you must use the JSP:

You can store the output stream to a file with a randomly generated name, then reference the file in the JSP. You need to make sure the output directory is in the web server's path.

This also comes with its own problems:

  • You need to manage the filesystem in a way that deletes old files (so your server's disk will fill up).
  • You need to manage synchronization to the file (no two server threads should update the same file).
  • Oh, and you must make sure that images generated by one user are not visible by another.

I've seen plenty of people do this kind of thing, I'm sure there is a library.

Justin