0

I have created a servlet like this given below:

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class otpcheck extends HttpServlet {


/**
 * Handles the HTTP <code>POST</code> method.
 *
 * @param request servlet request
 * @param response servlet response
 * @throws ServletException if a servlet-specific error occurs
 * @throws IOException if an I/O error occurs
 */
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

    PrintWriter out =response.getWriter();
    Crypting c=new Crypting();
    BufferedImage imgKey;
    BufferedImage imgEnc;
    imgKey = ImageIO.read(new File("E:/Key.png"));
    imgEnc=ImageIO.read(new File("E:/E.png"));

    response.setContentType("text/html");
    out.println(
"<!DOCTYPE html>\n" +
"<html>\n" +
"    <head>\n" +
"      \n" +
"        <title>Online Banking</title>\n" +
"        \n" +
"        <link rel=\"stylesheet\" href=\"newcss.css\">\n" +
"    </head>\n" +
"<!DOCTYPE html>\n" +
"\n" +
"        <div class=\"wrapper\">\n" +
"            \n" +
"        <div class=\"header\">\n" +
"            <img src=\"header_1.jpg\" height=\"100%\" width=\"100%\"/>\n" +
"            </div>\n" +
"            <div class=\"navbar\">\n" +
"                \n" +
"            <ul>\n" +
"            <li><a href=\"index.jsp\">Home</a></li>\n" +
"            <li><a href=\"features.jsp\">Features</a></li>\n" +
"            <li id=\"last\"><a href=\"contact.jsp\">Contact Us</a></li>\n"     +
"            </ul>\n" +
"            </div>" +
"\n" +
"<div class='content'>\n" +
"<div class=\"user_login\">");
    out.println("<p>Scan the QR Image to get OTP</p>");
     BufferedImage imgDec=Crypting.decryptImage(imgKey,imgEnc);
    response.setContentType("image/png");
    OutputStream os=response.getOutputStream();
    ImageIO.write(imgDec,"png",os);
    out.println("<form action=\"otpvalidate\" method=\"POST\"    enctype=\"multipart / form - data\">Enter OTP:<input type=\"password\" name=\"otp\"/>\n<input type=\"submit\" value=\"SUBMIT\" name=\"submit\" /></form >");
    out.println("</div>\n" +
"</div>\n" +
"<!DOCTYPE html>\n" +
"        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-    8\">\n" +
"        <div class=\"footer\">\n" +
"<ul>\n" +
"                   \n" +
"                   <div class=\"footer_content\">\n" +
"                   <li><a href=\"features.jsp\">Features </a></li>\n" +
"                   <li><a href=\"contact.jsp\"> Contact</a></li>\n" +
"                 \n" +
"                   <li><a href=\"safeonlinebanking.jsp\">Safe online Banking tips</a></li>\n" +
"                   \n" +
"                   <li style=\"padding-left:450px;\">Copyright&copy;2017   onlinebanking.com</li>\n" +
"                   \n" +
"                   </div>\n" +
"                   </ul>                    \n" +
"       \n" +
"    \n" +
"    \n" +
" </div>\n" +
"           </div> \n" +
"    </body>\n" +
"</html>\n" +
"\n" +
"</html>");

}


}

Since the image is dynamically generated(i.e decrypted)I can't save it as a file in filesystem.So I used OutputStream and response.setContentType("image/png") for displaying image. But I also need to generate a input and button using html.So I used another response.setContentType("text/html") for displaying html.

My problem is I am getting error which says java.lang.IllegalStateException: getWriter() has already been called for this response.So the content type response are conflicting each other.

Pls help me to resolve this error!!!

SKJ
  • 91
  • 1
  • 14
  • Please read my comments in @reos answer, and let me know if I understand your situation correctly. Also, no, you cannot write two different responses to the same response writer (text/html and then image/png). A workaround could be that you encode your image to base64 and send that as data for your `` tag. Have a look [here](http://stackoverflow.com/questions/10226046/java-convert-image-to-base64). If this is something you can do, I can elaborate more on this in a proper answer later. – Chetan Jadhav CD Feb 23 '17 at 21:34
  • @ChetanJadhavCD Yes you have understood my situation correctly.I am doing decryption on the fly.I don't want to save decrypted image in server or database as image will become static and these image are like some sort of OTP only for one time use. – SKJ Feb 24 '17 at 08:46
  • @ChetanJadhavCD it can be used by only one user for one session only.So these images `Key.png,E.png,D.png` are dynamic. – SKJ Feb 24 '17 at 08:48

3 Answers3

0

In the HTTP protocol you access resources. Each resource has its own type.

In your example you have at least 3 resources, one for the HTML page, one for key.png and one for e.png

What to do?

You can have your servlet that serves only your HTML page, and in the HTML page you can have the image tag pointing to the resources of the images

<html>
...
<img src="http://miserver/key.png">
<img src="http://miserver/e.png">

For the images you can put them in the war file and the server serves the images.

But if your images are store out of your war like a database, you can make other servlet that serves your images. In the SRC property of the IMG tag you put the URL of that servlet.

reos
  • 8,766
  • 6
  • 28
  • 34
  • I guess the OP is doing some kind of decryption on the image files on the fly, and also he mentions some restriction on him being able to save the decrypted file to disk, so this approach would not be applicable for him.. – Chetan Jadhav CD Feb 23 '17 at 20:30
  • 1
    Why not ? with decryption or without this works. If he needs to do decryption he needs to put the decryption code inside the servlet that returns the image. – reos Feb 23 '17 at 20:34
  • From his posted code, it looks like `imgKey` is some sort of key(in a png file!) to decrypt the encoded `imgEnc` file. He does the decryption using `BufferedImage imgDec=Crypting.decryptImage(imgKey,imgEnc);`. So now, the actual image to be sent to the browser is in the `imgDec` BufferedImage object. Your approach would require him to write this BufferedImage object to file, so that it can be pointed to using the ` – Chetan Jadhav CD Feb 23 '17 at 21:25
  • I understand it differently. I understand that he is NOT uploading a image. He needs to return a HTML page with two images in it. But he is writing the two images in the response bytes of the html. That is why I recommended this solution. If he wants to upload the images is a totally different solution. – reos Feb 23 '17 at 21:33
  • No no.. He is not uploading anything. My understanding is that he has encrypted images stored on the server, which he is decoding within his servlet, and then wants to send the image along with the other HTML stuff back to the client. He cannot save those images to the server after decryption (could be a policy thing, since those images are encrypted), which is why in his HTML he cannot point to them using `` tags. – Chetan Jadhav CD Feb 23 '17 at 21:37
0

You can serve both HTML and PNG from the same Servlet provided that:

  • for each request you only serve one of them, not both at once
  • it's deducible from the request which content must be served
  • you map the servlet to all needed URLs or patterns accordingly

For example you could map the servlet to both /onlinebanking.html and /onlinebanking.png and deduce from the extension of the request URI if you have to serve the HTML or the PNG content. Or map only to /onlinebanking and always send HTML unless requested otherwise by using e.g. /onlinebanking?content=image i.e. evaluating the query string or query parameters to make a decision.

Markus Benko
  • 1,507
  • 8
  • 8
0

First of all,Thank you all for your contributions.I found an answer and its working.

I created a servlet to return the image.Then I created a jsp file to fetch that image by giving URL as <img src="${pageContext.request.contextPath}/otpcheck" />. And its working good. Here is the code.

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class otpcheck extends HttpServlet {



@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {


    Crypting c=new Crypting();
    BufferedImage imgKey;
    BufferedImage imgEnc;
    imgKey = ImageIO.read(new File("E:/Key.png"));
    imgEnc=ImageIO.read(new File("E:/upload/E.png"));
     BufferedImage imgDec=Crypting.decryptImage(imgKey,imgEnc);
    response.setContentType("image/png");
    OutputStream os=response.getOutputStream();
    ImageIO.write(imgDec,"png",os);
}
}

And the jsp is as follows:

<img src="${pageContext.request.contextPath}/otpcheck" />
    <form action="otpvalidate" method="POST" enctype="multipart/form-data">
        Enter OTP:<input type="password" name="otp"/><input type="submit" value="SUBMIT" name="submit" />
    </form>

I referred some answers given by BalusC.That's how I got code working.

SKJ
  • 91
  • 1
  • 14