Rendering a bytestream as a PNG file via ServletOutputStream

Discussions

Web tier: servlets, JSP, Web frameworks: Rendering a bytestream as a PNG file via ServletOutputStream

  1. Hi,

    I have been trying to display a PNG file on the browser, unfortunately it gets display on the browser as a byte stream instead of a PNG file.

    Given below are the steps in the program : -

    1. My java program reads a stream of bytes into a byteArray object. This is happening correctly since the number of bytes read match the file size.
    2. Get the servlet handle (i.e. servletresponse) using the PageContext.getResponse() method in the javax.servlet.jsp.PageContext
    3. Get the ServletOutputStream using response.getOutStream()
    4. Setting the contenttype to "image/png"
    5. Write the outputstream using ServletOutputStream.write(byteArray)

    This java program is being called as a custom defined tag inside a jsp program.

    I'd appreciate, if anybody tell me what I'm missing out here or what i'm doing wrong?

    Thanks


  2. Hmm...it sounds like the browser isn't rendering your bytestream as an image. The only way to get a browser to render a bytestream as an image is to use the HTML <img> tag or another image tag like <input type="image">. One thing you can do is to take that servlet or jsp, give it a URL in your application, and then use that URL in the src attribute of an image tag.

    e.g. Servlet class is com.mycompany.ImageStreamer. Register this servlet with URL=/ImageStreamer. In your html, call the servlet with <img name="image1" src="/ImageStreamer?imageId=1" border="0">. This is assuming that your ImageStreamer servlet is setup to stream any image given an ID. If not, just leave off the query string.

    Hope this helps,

    Andy
  3. The requirement is to invoke the url via a custom defined tag. Giving the url in the src= parameter of the IMG tag works just fine. But I cannot use this approach.

    Given below are the methods that reads the bytestream & writes to the servletoutputstream : -

            //constructs the url to invoke the chart server
            public String buildUrl()
            {
    //append the Http query String to the URL
    StringBuffer buffer = new StringBuffer();
    buffer.append(chartUrl);
    buffer.append("?");
    buffer.append(query);
                    return buffer.toString();
            }

           //gets the PNG data from the chart server
            public void getByteInputStream()
            {
                    try{
                            String urlStr = buildUrl();
                            URL url = new URL(urlStr);
      inStream=url.openStream();
    int size = 0;
    int bytesRead =0;
    int len = inStream.available();
    System.out.println("size : "+len);
    byte b[] = new byte[len];
    while(bytesRead<len){
       size=inStream.read(b,size,(len-bytesRead));
    if (size == -1)
    break;
    bytesRead=+size;
    }
    inStream.close();
                            out = getOutputStream();
    out.write(b);
    out.flush();

                    }
    catch(IOException ioe){
    System.out.println(ioe);
    }
    //sets the query String
    public void setQuery(String s)
    {
    System.out.println("Setting Query"+s);
    query = s;
    System.out.println("QueryString = "+query);
    }

    //sets the ServletOutputStream
    public ServletOutputStream getOutputStream() throws IOException
    {
    if (pageContext != null)
    {
    response=pageContext.getResponse();
    ServletOutputStream outstream = response.getOutputStream();
    response.setContentType("image/png");
    return(outstream);
    }
    else
    return(null);
    }


    What am I mising here?


  4. There's nothing wrong with your code that streams the bytes back on the reponse output stream. I think the problem is that the stream of bytes isn't going to the right place. A browser only understands HTML. In your HTML you need an <img> tag. That tag tells the browser to send a SEPARATE request for a stream of bytes that it will render as an image. You can't place a custom tag in your JSP that simply streams bytes back. The browser will not render those bytes as an image, even if the content-type is set to image/png. The user can save those bytes to file and then open them up in a viewer, but I don't think that's what you want.

    I know of no way to embed bytes into an HTML document and make the browser render them, unless you write a plugin or applet.

    If you want to use JSP and HTML, I would suggest making your custom tag build the <img> tag, take the code that does the streaming and put it in a Servlet. Your custom tag should set the src attribute of the img tag to call your servlet to get the stream of bytes for the image.

    Andy Nguyen
    anguyen@itginc.com
  5. Thanks Andy, I figured this out yesterday. Anyways, found a work around solution to this problem. So its the IMG tag again calling the url(built via a java program). Therefore, the custom defined tag is out of the picture.

    Mary
    mary_virginia at netkracker dot com