Question

I'm using SimpleCaptcha to secure our contact form. It works well, but only after reloading the page.

The Servlet is nl.captcha.servlet.StickyCaptchaServlet, so it should not change the image after reloads. But when first opening the page the image is just not loaded. However, after reloading everything works fine.

the web.xml

The captcha is served by an application running at /services.

<web-app>
  <servlet>
    <servlet-name>captcha</servlet-name>
    <servlet-class>nl.captcha.servlet.StickyCaptchaServlet<servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>captcha</servlet>
    <url-pattern>/captcha.png</url-pattern>
  </servlet-mapping>
</web-app>

the html

<img src="/services/captcha.png">

the server

I'm using tomcat-7.0.34 on a Windows 7 64bit machine with Java 1.7.0_07.

the question

Why does the image only show up after a reload? Any ideas?

Was it helpful?

Solution 2

Just do this way to by pass what emka86 had said.

<img src="/services/captcha.png" style="display:none"> (Duplicate part to fix the issue)

<img src="/services/captcha.png"> (The actual one)

Hope this helps for any future developer out there.

OTHER TIPS

there are several steps you can follow:

1> modify web.xml add your servlet that extends nl.captcha.servlet.StickyCaptchaServlet class

 <servlet>   
    <description></description>    
    <display-name>CustomCaptchaServlet</display-name>    
    <servlet-name>CustomCaptchaServlet</servlet-name>    
    <servlet-class>org.example.servlets.CustomCaptchaServlet</servlet-class>    
 </servlet>    
  <servlet-mapping>    
    <servlet-name>CustomCaptchaServlet</servlet-name>    
    <url-pattern>/CustomCaptchaServlet</url-pattern>    
  </servlet-mapping>

2> CustomCaptchaServlet.java

package org.example.servlets;    
import static nl.captcha.Captcha.NAME;    

import java.io.IOException;    

import javax.servlet.ServletException;    
import javax.servlet.http.HttpServlet;    
import javax.servlet.http.HttpServletRequest;    
import javax.servlet.http.HttpServletResponse;    
import javax.servlet.http.HttpSession;    

import nl.captcha.Captcha;    
import nl.captcha.servlet.CaptchaServletUtil;    
import nl.captcha.servlet.StickyCaptchaServlet;    

public class CustomCaptchaServlet extends StickyCaptchaServlet {    
    private static final long serialVersionUID = 1L;    

    /**
     * @see StickyCaptchaServlet#StickyCaptchaServlet()
     */
    public CustomCaptchaServlet() {
        super();
        // TODO Auto-generated constructor stub
    }


    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {    

        String _width = getServletConfig().getInitParameter("width");    
        String _height = getServletConfig().getInitParameter("height");    
        HttpSession session = request.getSession();    
        Captcha captcha;    
        if (session.getAttribute(NAME) == null) {    
            captcha = new Captcha.Builder(Integer.parseInt(_width), Integer.parseInt(_height))    
            .addText()    
            .gimp()    
            .addBorder()    
                .addNoise()    
                .addBackground()    
                .build();    
            session.setAttribute(NAME, captcha);    
            CaptchaServletUtil.writeImage(response, captcha.getImage());    
            return;    
        }    
        captcha = (Captcha) session.getAttribute(NAME);    
        CaptchaServletUtil.writeImage(response, captcha.getImage());    
    }    


    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {    

    }    

}    

Check that the web.xml has captcha.png while the HTML is referring to captcha.jpg.

Does that solve the issue?

The problem is that StickyCaptchaServlet is creating new captcha image for session. When you make initial request to a page you have no session id so StickyCaptchaServlet cannot connect you to any image created for a particular session.

After first request main servlet create session for you and send you back some kind of sessionId. With next request (also reload) you send to server request with recevied previously sessionId so now your StickyCaptchaServlet is possible to collect captcha image for your session because it knows that you are in any session.

Do you understand this explanation? Will it be helpfull for you?

Added after your question to resolve this problem.

You can add to your web app class which will implements HttpSessionListener. Then, in method sessionCreated you can add request to StickyCaptchaServlet with just created sessionId. According to StickyCaptchaServlet doc You just have to invoke doGet method of it with passed sessionId key. After that - when browser on your page will request for url /services/captcha.png it should get as response image created and prepared just before it by your HttpSessionListener implementation.

Other way is to use cliend side scripting and after page is loaded, with no image at all, just reload it - as this internal reload, for example JavaScript, the browser will know sessionId and will pass it through the request for captcha image. By reload I mean only reload image, not the whole page.

Will any of those suggestions resolve your problem? Give me a feedback about it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top