Struts Form CAPTCHA Code Example

The Struts Form Captcha code example shows how to add BotDetect CAPTCHA protection to a typical Struts form.

Captcha validation is integrated with other form fields validation, and only submissions that meet all validation criteria are accepted. It uses both xml and non-xml validation method.

If the Captcha is successfully solved but other field validation fails, the Captcha is hidden since the users have already proven they are human.

This kind of validation could be used on various types of public forms which accept messages, and are at risk of unwanted automated submissions.

For example, it could be used to ensure bots can't submit anything to a contact form, add guestbook entries, blog post comments or anonymous message board / forum replies.

Download the BotDetect Java CAPTCHA Generator archive to run this example

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-struts2-contact_form/ 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, and botdetect-jsp20.jar are in the classpath.

index.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="botDetect" uri="https://captcha.com/java/jsp"%>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>BotDetect Java CAPTCHA Validation: Struts 2 Form CAPTCHA Code Example</title>
    <link rel="stylesheet" href="stylesheet.css" type="text/css" />
  </head>
  <body>
    <s:form action="captchaAction" method="post"  theme="css_xhtml" class="column" id="form1">
      <h1>BotDetect Java CAPTCHA Validation: <br /> Struts 2 Form CAPTCHA Code Example</h1>
      <fieldset>
        <legend>CAPTCHA included in Struts form validation</legend>
        
        <s:textfield name ="user.name" label="Name" class="textbox"  />
        <s:textfield name ="user.email" label="Email" class="textbox" />
        <s:textarea name="user.message" label="Message" rows="5" cols="40" class="inputbox" />
        
        <label for="captchaCode">Retype the characters from the picture:</label>
      
        <!-- Adding BotDetect Captcha to the page -->    
        <botDetect:captcha id="formCaptcha" userInputID="captchaCode"/>
        
        <br/>
        <s:textfield name="captchaCode" id="captchaCode" class="textbox" />
        <s:submit name="validateCaptchaButton" label="Validate" id="validateCaptchaButton"/>
      </fieldset>
    </s:form>
  </body>
</html>

Beside the Captcha code input textbox, the example form contains three other fields, which are all validated the same way in form processing code. Those elements are generated by struts 2 tags.

ContactFormAction.java

package com.captcha.botdetect.examples.struts.form_captcha.actions;

import org.apache.struts2.ServletActionContext;

import com.captcha.botdetect.examples.struts.form_captcha.bean.User;
import com.captcha.botdetect.web.servlet.Captcha;
import com.opensymphony.xwork2.ActionSupport;

public class ContactFormAction extends ActionSupport {

  private static final long serialVersionUID = 1L;
  
  private User user;
  private String captchaCode;

  public String getCaptchaCode() {
    return captchaCode;
  }

  public void setCaptchaCode(String captchaCode) {
    this.captchaCode = captchaCode;
  }
  
  public User getUser() {
    return user;
  }

  public void setUser(User user) {
    this.user = user;
  }

  public String execute() {
    return SUCCESS;
  }
  
  public void validate() {
    if (captchaCode == null) {
      addFieldError("captchaCode", "Please enter the verification code.");
    } else {
      Captcha captcha = Captcha.load(ServletActionContext.getRequest(), "formCaptcha");
      boolean isHuman = captcha.validate(captchaCode);
      if (!isHuman) {
        addFieldError("captchaCode", "Incorrect code.");
      }

      // reset captcha code textbox
      captchaCode = null;
    }
  }
}

This is the main action of the application. The validate method is called to validate the captcha code. Other fields are validate using an xml file.

User.java

package com.captcha.botdetect.examples.struts.form_captcha.bean;

public class User {

  private String name, message, email;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getMessage() {
    return message;
  }

  public void setMessage(String message) {
    this.message = message;
  }

  public String getEmail() {
    return email;
  }

  public void setEmail(String email) {
    this.email = email;
  }
  
}

This is simply the java bean that stores the information of users.

success.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>BotDetect Java CAPTCHA Validation: Struts 2 Form CAPTCHA Code Example</title>
    <link rel="stylesheet" href="stylesheet.css" type="text/css" />
  </head>
  <body>
    <div class="column">
      <h1>BotDetect Java CAPTCHA Validation: <br /> Struts 2 Form CAPTCHA Code Example</h1>
      <h2>View Messages</h2>
      
      <div class="message">
        <p>Name: <s:property value="user.name"/></p>
        <p>Email: <s:property value="user.email"/></p>
        <p>Message: <s:property value="user.message"/></p>
      </div>
      
      <p class="navigation"><a href="index.jsp">Back</a></p>
    </div>
  </body>
</html>

A simple page which would be loaded if the form fields are successfully validate.

validators.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
    "-//Apache Struts//XWork Validator Definition 1.0//EN"
    "http://struts.apache.org/dtds/xwork-validator-definition-1.0.dtd">
 
<validators>
  <validator name="requiredstring" class="com.opensymphony.xwork2.validator.validators.RequiredStringValidator"/>
  <validator name="email" class="com.opensymphony.xwork2.validator.validators.EmailValidator"/>
  <validator name="stringlength" class="com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator"/>
</validators>

The validators used in this application must be declared in this file.

struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
  "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
  "http://struts.apache.org/dtds/struts-2.5.dtd">

<struts>
  <constant name="struts.devMode" value="true" />
  <constant name="struts.action.excludePattern" value="/botdetectcaptcha"/>
    
  <package name="formCaptcha" extends="struts-default">
    <action name="captchaAction"
        class="com.captcha.botdetect.examples.struts.form_captcha.actions.ContactFormAction" method="execute">
      <result name="input">/index.jsp</result>
      <result name="success">/WEB-INF/success.jsp</result>
    </action>
  </package>
</struts>

In struts.xml configuration file, you also need to add exclude directive for CaptchaServlet to Struts 2 filter.

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="struts2-jquery-showcase" version="2.5"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        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">
  <session-config>
    <session-timeout>
      30
    </session-timeout>
  </session-config>
  
  <display-name>Struts 2 Web Application</display-name>

  <filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
  </filter>

  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-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>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

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


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.