getOutputStream () error has already been called for this response

1

I have the following error in my application:

getOutputStream () has already been called for this response.

Ok, the code snippet that is causing this error is as follows:

boolean hasLogoLogin = new BrandResourceDao().selectByTag(BrandResourceCnt.TAG_BRANDLOGOLOGIN) != null;
boolean hasLogoDefault = new BrandResourceDao().selectByTag(BrandResourceCnt.TAG_BRANDLOGODEFAULT) != null;
boolean hasLogoHight = new BrandResourceDao()
            .selectByTag(BrandResourceCnt.TAG_BRANDLOGOHIGHLIGHTEDE) != null;
boolean hasBackground = new BrandResourceDao().selectByTag(BrandResourceCnt.TAG_BRANDBACKGROUND) != null;

That's nothing more than a select to check if the images saved at any given time in the application really are there. The code just below is repeated for each return of the above selects (Each one for its value).

<img id="imgLogoLogin"
    <%=hasLogoLogin
       ? "src='loadImage.jsp?" + Params.TAG + "=" + BrandResourceCnt.TAG_BRANDLOGOLOGIN + "'" : ""%>
style="max-width: 325px; max-height: 200px; width: auto; height: auto;" />

And here the loadImage.jsp that searches the database for the image, converts and displays it in the application.

try {
        String tag = request.getParameter(Params.TAG);
        BrandResourceDao dao = new BrandResourceDao();
        BrandResource brand = dao.selectByTag(tag);

if (brand != null) {
   byte[] bytes = Base64.decode(brand.getValue());
   response.setContentType("image/gif");
   OutputStream oImage = response.getOutputStream();  <-- É culpa desse cara aí
   oImage.write(bytes);
   oImage.flush();
   oImage.close();
}
    } catch (Exception e) {
        e.printStackTrace();
    }

Please no swearing by the style of the tag (img) I will put it in the css in the future.

Well my doubt is: How to solve this? I need to change the structure is obvious. But I'm a beginner and I do not know how to do it. Does anyone have any ideas for making my life a little easier?

    
asked by anonymous 08.03.2016 / 15:08

1 answer

1

It is part of the Java API that you can only retrieve an output object once from response , either through the getOutputStream method or the getWriter method.

If the code in question is inside a JSP, you already have an implicit object out that can use to write the data. Calling the response.getOutputStream method is not only unnecessary as an error.

The difference here is that out is PrintWriter type, so you'll have to adapt the code a bit.

This means that it is not possible to write a byte output from a JSP. I have already seen implementations that converted the bytes to a String and then wrote the String using out.write(str) , but there are cases where there may be information loss.

The ideal output for your case is not to use a JSP, but to write a Servlet where you can use getOutputStream properly.

Example ( source ):

public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {

       ServletContext cntx= getServletContext();
      // Get the absolute path of the image
      String filename = cntx.getRealPath("Images/button.png");
      // retrieve mimeType dynamically
      String mime = cntx.getMimeType(filename);
      if (mime == null) {
        resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        return;
      }

      resp.setContentType(mime);
      File file = new File(filename);
      resp.setContentLength((int)file.length());

      FileInputStream in = new FileInputStream(file);
      OutputStream out = resp.getOutputStream();

      // Copy the contents of the file to the output stream
       byte[] buf = new byte[1024];
       int count = 0;
       while ((count = in.read(buf)) >= 0) {
         out.write(buf, 0, count);
      }
    out.close();
    in.close();

}
    
09.03.2016 / 07:18