I have an issue in my application using where I have a Captcha component built as a JSF Custom Tag:
in my JavaEE 6 webapp I use: JSF 2.1 + Jboss Richfaces 4.2.3 + EJB 3.1 + JPA 2.0 + PrettyFaces 3.3.3
I have a JSF2 custom tag that is:
<tag>
<tag-name>captcha</tag-name>
<source>tags/captcha.xhtml</source>
</tag>
in my XHTML page called accountEdit.xhtml I have the captcha being displayed:
<ui:fragment rendered="#{customerMB.screenComponent.pageName eq 'create'}">
<div class="form_row">
<label class="contact"><strong>#{msg.captcha}:</strong>
</label>
<atl:captcha></atl:captcha>
</div>
</ui:fragment>
in captcha.xhtml:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<table border="0">
<tr>
<td>
<h:graphicImage id="capImg" value="#{facesContext.externalContext.requestContextPath}/../captcha.jpg" />
</td>
<td><a4j:commandButton id="resetCaptcha" value="#{msg.changeImage}" immediate="true" action="#{userMB.resetCaptcha}" >
<a4j:ajax render="capImg" execute="@this" />
</a4j:commandButton></td>
</tr>
<tr>
<td><h:inputText value="#{userMB.captchaComponent.captchaInputText}" /></td>
</tr>
</table>
</ui:composition>
in my web.xml I have configured a CaptchaServlet that handles the request for generating a captcha during runtime:
<servlet>
<servlet-name>CaptchaServlet</servlet-name>
<servlet-class>com.myapp.web.common.servlet.CaptchaServlet</servlet-class>
<init-param>
<description>passing height</description>
<param-name>height</param-name>
<param-value>30</param-value>
</init-param>
<init-param>
<description>passing width</description>
<param-name>width</param-name>
<param-value>120</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CaptchaServlet</servlet-name>
<url-pattern>/captcha.jpg</url-pattern>
</servlet-mapping>
My CaptchaServlet implementation:
public class CaptchaServlet extends HttpServlet {
/**
*
*/
private static final long serialVersionUID = 6105436133454099605L;
private int height = 0;
private int width = 0;
public static final String CAPTCHA_KEY = "captcha_key_name";
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
height = Integer
.parseInt(getServletConfig().getInitParameter("height"));
width = Integer.parseInt(getServletConfig().getInitParameter("width"));
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse response)
throws IOException, ServletException {
// Expire response
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Max-Age", 0);
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Graphics2D graphics2D = image.createGraphics();
Hashtable<TextAttribute, Object> map = new Hashtable<TextAttribute, Object>();
Random r = new Random();
String token = Long.toString(Math.abs(r.nextLong()), 36);
String ch = token.substring(0, 6);
Color c = new Color(0.6662f, 0.4569f, 0.3232f);
GradientPaint gp = new GradientPaint(30, 30, c, 15, 25, Color.white,
true);
graphics2D.setPaint(gp);
Font font = new Font("Verdana", Font.CENTER_BASELINE, 26);
graphics2D.setFont(font);
graphics2D.drawString(ch, 2, 20);
graphics2D.dispose();
HttpSession session = req.getSession(true);
session.setAttribute(CAPTCHA_KEY, ch);
OutputStream outputStream = response.getOutputStream();
ImageIO.write(image, "jpeg", outputStream);
outputStream.close();
}
}
When I run this app on Glassfish 3.1.1 when the Servlet's doGet() method is called while rendering
for the HttpServlet doGet() method that renders:
<h:graphicImage id="capImg" value="#{facesContext.externalContext.requestContextPath}/../captcha.jpg" />
doGet() renders only once for Google Chrome, thus rendering correctly.
For Firefox and IE doGet() renders twice updating the Captcha Key but not updating the painted Captcha Image on the page.
If anyone might know what could be a fix for this and why it has this behavior for Chrome different from other browsers please let me.
Thanks in advance!