JSF Validator CAPTCHA Code Example

The JSF Validator Captcha code example shows how to integrate BotDetect CAPTCHA validation with standard JSF page validation functionality and other validator controls.

Download the BotDetect Java CAPTCHA Generator archive to run this example

JSF 2.0+

Within this page, the root folder of the extracted archive is referred as the <BDC-DIR>.

This example is in the <BDC-DIR>/examples/t_api-captcha-jsf2.0-api_basics-validator_tag/ folder; and contains the following files:

Running Example

This example's war file (in BotDetect download package) already embeds all dependencies.

In case you are making this example from scratch in your IDE, you need to ensure botdetect.jar, botdetect-servlet.jar, botdetect-jsp20.jar, and botdetect-jsf20.jar are in the classpath.

index.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
<%@taglib prefix="botDetect" uri="https://captcha.com/java/jsf"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
  "http://www.w3.org/TR/html4/loose.dtd">
<f:view>
  <html>
    <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
      <title>BotDetect Java CAPTCHA Validation: JSF Validator CAPTCHA Code Example</title>
      <link rel="stylesheet" href="stylesheet.css" type="text/css"/>
    </head>
    <body>
      <h:form prependId="false" styleClass="column">
        <h1>BotDetect Java CAPTCHA Validation:<br/> JSF Validator CAPTCHA Code Example</h1>
        <fieldset>
          <legend>Java CAPTCHA Validation</legend>
          <h:outputLabel for="inputName" value="Name:"/>
          <h:inputText id="inputName" validatorMessage="Missing name">
            <f:validateLength minimum="2"/>
          </h:inputText>
          <h:message for="inputName" styleClass="incorrect"/>
          
          <h:outputLabel for="captchaCode" value="Retype the characters from the picture:"/>
          <!-- Adding BotDetect Captcha to the page -->
          <botDetect:jsfCaptcha id="exampleCaptcha"
                     userInputID="captchaCode" />
          
          <div class="validationDiv">
            <h:inputText id="captchaCode" value="#{validatorExample.captchaCode}"
                   validatorMessage="Incorrect code">
              <f:validator validatorId="exampleValidator"/>
              <f:attribute name="captchaId" value="exampleCaptcha"/>
            </h:inputText>
            <h:message for="captchaCode" styleClass="incorrect"/>
          </div>
          
          <h:commandButton  action="#{validatorExample.submit}" value="Submit"/>
          
          <h:outputText value="Validation passed." styleClass="correct" rendered="#{validatorExample.validated}"/>
        </fieldset>
      </h:form>    
    </body>
  </html>
</f:view>

In order to use a custom JSF Validator to validate user Captcha code input, we have to declare a validator of the Captcha code text box (<f:validator validatorId="exampleValidator"/>). Also, we have to add Captcha Id as component's attribute to Captcha code text box (<f:attribute name="captchaId" value="exampleCaptcha"/>).

ExampleValidator.java

package com.captcha.botdetect.examples.jsf.validator;

import com.captcha.botdetect.web.servlet.Captcha;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.FacesValidator;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;
import javax.servlet.http.HttpServletRequest;

@FacesValidator(value="exampleValidator")
public class ExampleValidator implements Validator {

  @Override
  public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
    String captchaId = (String) component.getAttributes().get("captchaId");
    HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
    
    // validate the Captcha to check we're not dealing with a bot
    Captcha captcha = Captcha.load(request, captchaId);
    boolean isHuman = captcha.validate((String) value);
    if (!isHuman) {
      FacesMessage message = new FacesMessage();
      throw new ValidatorException(message);
    }
  }

}

In validate method of the JSF custom validator first we have to obtain Captcha id from component's attributes.

Using Captcha id instantiate Captcha object and validate user input in usual way.

ValidatorExample.java

package com.captcha.botdetect.examples.jsf.validator.view;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

@ManagedBean(name="validatorExample")
@RequestScoped
public class ValidatorExample {
  
  private String captchaCode;
  private boolean validated;

  public ValidatorExample() {
  }

  public String getCaptchaCode() {
    return captchaCode;
  }

  public void setCaptchaCode(String captchaCode) {
    this.captchaCode = captchaCode;
  }

  public boolean isValidated() {
    return validated;
  }

  public void submit(){
    captchaCode = null;
    validated = true;
  }
}

Managed bean has no specific BotDetect Captcha code since all validation is done in custom validator. Form's action method submit() is invoked after Captcha validation is passed so property validated (which is used to display message on the form) is set true.

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
  http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  id="WebApp_ID" version="2.5">

  <context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
  </context-param>

  <context-param>
    <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
    <param-value>.jsp</param-value>
  </context-param>

  <context-param>
    <param-name>facelets.VIEW_MAPPINGS</param-name>
    <param-value>*.xhtml</param-value>
  </context-param>     
 
  <context-param>
    <param-name>javax.faces.VALIDATE_EMPTY_FIELDS</param-name> 
    <param-value>true</param-value>
  </context-param>    

  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/faces/*</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.faces</url-pattern>
  </servlet-mapping>

  <servlet>
    <servlet-name>BotDetect Captcha</servlet-name>
    <servlet-class>com.captcha.botdetect.web.servlet.CaptchaServlet</servlet-class>
  </servlet>    
  <servlet-mapping>
    <servlet-name>BotDetect Captcha</servlet-name>
    <url-pattern>/botdetectcaptcha</url-pattern>
  </servlet-mapping> 

  <welcome-file-list>
    <welcome-file>faces/index.jsp</welcome-file>
  </welcome-file-list>
  
  <session-config>
    <session-timeout>
      30
    </session-timeout>
  </session-config>
   

</web-app>

In WEB-INF/web.xml file we register CaptchaServlet used for BotDetect Captcha requests.

JSF 1.2

Example Location

The JSF 1.2 Validator CAPTCHA code example is included in the
examples/traditional-api/bdc4-traditional-api-jsf12-validator-captcha-example.war file of the download package.


Please Note

BotDetect Java Captcha Library v4.0.Beta3.7 is an in-progress port of BotDetect 4 Captcha, and we need you to guide our efforts towards a polished product. Please let us know if you encounter any bugs, implementation issues, or a usage scenario you would like to discuss.