Generate own Captcha in JSF 2.0 and Richfaces.
captcha.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:a4j="http://richfaces.org/a4j">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>TODO supply a title</title>
</head>
<body>
<h:form>
<table border="0">
<tr>
<td>
<h:graphicImage id="capimg" value="#{facesContext.externalContext.requestContextPath}/../Captcha.jpg"/>
</td>
<td>
<h:commandButton value="Change Image">
<a4j:support reRender="capimg" event="onclick"/>
</h:commandButton>
</td>
</tr>
<tr>
<td>
<h:inputText value="#{CaptchaAction.validate}"/>
</td>
<td>
<h:commandButton action="#{CaptchaAction.execute}" value="Click"/>
</td>
</tr>
</table>
</h:form>
</body>
</html>
Output :
web.xml
<servlet>
<servlet-name>Captcha</servlet-name>
<servlet-class>com.captcha.MyCaptcha</servlet-class>
<init-param>
<description>passing height</description>
<param-name>height</param-name>
<param-value>30</param-value>
</init-param>
<init-param>
<description>passing height</description>
<param-name>width</param-name>
<param-value>120</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Captcha</servlet-name>
<url-pattern>/Captcha.jpg</url-pattern>
</servlet-mapping>
MyCaptcha.java (Servlet)
package com.captcha;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.servlet.http.*;
import javax.servlet.*;
import java.io.*;
import java.awt.*;
import java.util.*;
import java.awt.font.TextAttribute;
public class MyCaptcha extends HttpServlet {
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();
}
}
CaptchaAction.java(JSF Managed Bean)
package com.captcha;
import com.sun.facelets.FaceletContext;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
@ManagedBean(name = "CaptchaAction")
@ViewScoped
public class CaptchaAction {
public CaptchaAction() {
}
String validate;
public String getValidate() {
return validate;
}
public void setValidate(String validate) {
this.validate = validate;
}
public String execute() throws Exception {
HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
Boolean isResponseCorrect = Boolean.FALSE;
javax.servlet.http.HttpSession session = request.getSession();
String parm = validate;
String c = (String) session.getAttribute(MyCaptcha.CAPTCHA_KEY);
if (parm.equals(c)) {
return "success";
} else {
return "failed";
}
}
}

Eventhough a4j:support is used the page is getting refreshed. Rerender is not working.
Unless the page is refreshed the the image is not changed. Please suggest us how we can do with ajax or a4j:support without refreshing the page.
Please advice as early as possible
Try this :
Keep the controls inside
CAPTCHA CONTROLS
When you say keep the controls inside de captcha controls.. what do you refer with this??.. a need help with this thing.. thanks¡¡..
thanks dude! you save my life!
@mehmet :)
What i don’t realize is actually how you’re not actually a lot more smartly-appreciated
than you might be now. You’re so intelligent. You know thus considerably relating to this subject, produced me individually consider it from so many various angles. Its like men and women don’t seem
to be interested unless it’s one thing to do with Girl gaga! Your individual stuffs nice. At all times take care of it up!
Pingback: kaptcha, JSF, RichFaces, captcha | Business World TI
Thanks for the code. Saved me a lot of time. Using it with JSF2.0 (without RichFaces) and everything is working like charm. Thanks once again.
welcome duke :)
Works in 2014!
Thanks, very helpful. I’ll prefer to change CaptchaAction to Validator:
@FacesValidator
public class CaptchaValidator implements Validator {
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
String userInput = (String) value;
String captcha = (String) Faces.getSession().getAttribute(MyCaptcha.CAPTCHA_KEY);
if (userInput == null || captcha == null || !userInput.equals(captcha)) {
FacesMessage message = new FacesMessage();
message.setDetail(“Wrong captcha”);
message.setSummary(“Wrong captcha”);
message.setSeverity(FacesMessage.SEVERITY_ERROR);
throw new ValidatorException(message);
}
}
}
Use of Omnifaces’s Faces.getSession() can be changed to context.getExternalContext().getSession(true)
Add this to any form (in RichFaces 5 r:ajax instead of a4j:support):