Child pages
  • Struts integration
Skip to end of metadata
Go to start of metadata

Start with download

struts-mailreader.zip

Introduction

This document is a tutorial that demonstrates how to integrate JCaptcha with a Struts based Web application using the Jcaptcha Struts module.
It Uses the struts-mailreader application bundled with the Struts distribution as the base web application to captcha-ize.

This tutorial is devided into 5 Steps.

  • Step 1 : Prerequisites
  • Step 2 : install and configure the jcaptcha struts plugin
  • Step 3 : Indentify the to be captchai-zed page flow
  • Step 4 : Short cut the identified actions with captcha action
  • Step 5 : Modify the input page

Prerequisites

Install the struts-mailreader sample application in your favorite J2EE container.
Just deploy the war or the exploded war into your favorite application container deploy directory.
Install the jcaptcha struts plugin

  • Copy the jcaptcha jar to the WEB-INF/lib dir of the struts-mailreader web-app : jcaptcha-all-$version.jar
  • Copy the jcaptcha third parties jars to the WEB-INF/lib dir of the struts-mailreader web-app : ehcache-1.0.jar
  • Add the following plugin declaration at the end of the struts config file
                        <plug-in className="com.octo.captcha.module.struts.CaptchaServicePlugin"/>
                        
          

(there's many settable property available, but none are required, this is detailed in the module documentation).

Indentify the to be captchai-zed page flow

We want to captcha-ize the registration page flow in order to avoid robot registration spam...
This page flow concerns the following elements in struts-mailreader struts-config-registration.xml (using wildcard!!) file :

       
 ...

 <!-- ========== Form Bean Definitions =================================== -->
  <form-beans>

    <!-- Registration form bean -->
    <form-bean      name="RegistrationForm"
                    type="org.apache.struts.webapp.example.RegistrationForm"/>

  </form-beans>

  <!-- ========== Global Forward Definitions ============================== -->
  <global-forwards>
    <forward   name="Registration"         path="/Registration.jsp"/>
  </global-forwards>

  <!-- ========== Action Mapping Definitions ============================== -->
  <action-mappings>

    <!-- Matches all edit actions (in this case, only user regstration) -->
    <action    path="/Edit*"
               type="org.apache.struts.webapp.example.Edit{1}Action"
               name="{1}Form"
              scope="request"
           validate="false">
      <forward name="success"              path="/{1}.jsp"/>
    </action>

    <!-- Matches all save actions (in this case, only user registration) -->
    <action    path="/Save*"
               type="org.apache.struts.webapp.example.Save{1}Action"
               name="{1}Form"
              scope="request"
              input="{1}"/>

  </action-mappings>


...

Short cut

So what we have to do next is to short cut this action (SaveRegistration.do) to introduce a jcaptcha challenge verification action before calling the 'real' action.
In order to do it, we will

  • create a new action called jcaptchaRegistration that will execute the 'real' action.
  • replace the 'real' action class in order to execute the jcapthca validation routine
  • Finaly add the render challenge action that will produce the image challenge to render.

The final configuration will look as follow :

               
                    <!-- Matches all edit actions (in this case, only user regstration) -->
                       <action    path="/Edit*"
                                  type="org.apache.struts.webapp.example.Edit{1}Action"
                                  name="{1}Form"
                                 scope="request"
                              validate="false">
                         <forward name="success"              path="/{1}.jsp"/>
                       </action>



                    <!-- Transform the wildCardAction to use the jcaptcha validation routine-->

                                  <action
                                      path="/SaveRegistration"
                                      type="com.octo.captcha.module.struts.VerifyCaptchaChallengeAction"
                                      name="RegistrationForm"
                                      scope="request"
                                      input="Registration"
                                      validate="false"
                                      >
                                      <forward name="success" path="/jcaptchaRegistration.do"/>

                                  </action>


                    <!-- Add the real action -->

                    <action
                        path="/jcaptchaRegistration"
                        type="org.apache.struts.webapp.example.SaveRegistrationAction"
                        name="RegistrationForm"
                        scope="request"
                        input="Registration"
                        >


                    </action>

                    <!-- add the render action-->
                    <action
                        path="/jcaptcha"
                        type="com.octo.captcha.module.struts.image.RenderImageCaptchaAction"
                        >


                    </action>

Modify the input jsp

  • adding the jcatcha taglib declaration
  • adding a jcaptcha:message tag to add the failed message
  • adding a jcaptcha:question tag to add the question
  • adding an jcaptcha text input form
  • adding an jcaptcha challenge

                        <%@ page contentType="text/html;charset=UTF-8" language="java" %>
                        <%@ taglib uri="/tags/app"    prefix="app" %>
                        <%@ taglib uri="/tags/struts-bean" prefix="bean" %>
                        <%@ taglib uri="/tags/struts-html" prefix="html" %>
                        <%@ taglib uri="/tags/struts-logic" prefix="logic" %>

                            <%-- Add the jcaptcha taglib--%>
                        <%@ taglib uri="jcaptcha" prefix="jcaptcha"%>

                        <logic:equal name="RegistrationForm" property="action"
                                    scope="request" value="Edit">
                          <app:checkLogon/>
                        </logic:equal>

                        <html:html>
                        <head>
                        <logic:equal name="RegistrationForm" property="action"
                                    scope="request" value="Create">
                          <title><bean:message key="registration.title.create"/></title>
                        </logic:equal>
                        <logic:equal name="RegistrationForm" property="action"
                                    scope="request" value="Edit">
                          <title><bean:message key="registration.title.edit"/></title>
                        </logic:equal>
                        <html:base/>
                        </head>
                        <body bgcolor="white">

                        <html:errors/>

                        <%-- Add the message tag--%>
                        <jcaptcha:message/>

                        <html:form action="/SaveRegistration" focus="username"
                                 onsubmit="return validateRegistrationForm(this);">
                        <html:hidden property="action"/>
                        <table border="0" width="100%">

                         <%-- Add the jcaptcha form part--%>


                          <tr>
                            <th align="right">
                             <jcaptcha:question/>:
                            </th>
                            <td align="left">

                                                <%-- Add the image--%>

                                                <img src="jcaptcha.do"/>
                        <br/>
                                                <%-- Add the input tag--%>

                                                <input type="text"  name="jcaptcha_response" />

                            </td>
                          </tr>




                          <tr>
                            <th align="right">
                              <bean:message key="prompt.username"/>:
                            </th>
                            <td align="left">
                              <logic:equal name="RegistrationForm" property="action"
                                          scope="request" value="Create">
                                <html:text property="username" size="16" maxlength="16"/>
                              </logic:equal>
                              <logic:equal name="RegistrationForm" property="action"
                                          scope="request" value="Edit">
                        <%--
                                <bean:write name="RegistrationForm" property="username"
                                           scope="request" filter="true"/>
                        --%>
                            <html:hidden property="username" write="true"/>
                              </logic:equal>
                            </td>
                          </tr>
...               

Remarks and best practices

As you may have noticed :

  • We added a statistics page and links to demonstrate the manageable service features
  • The captcha test is hackable by directly using the real action : Choose a wird action name in order to avoid direct call
  • Chaining action as we just do in this tutorial is not recommended : Write your own action, use the sources of the VerifyCaptchaChallengeAction
  • As you can see, the update profil page flow is also captch-ized : Be carrefull when you choose your page flow to captcha-ize, you may split a page flow to captch-ize just a part of it
  • Use the user mailing list if you have more questions.
  • No labels

10 Comments

  1. Anonymous

    Hi,

    I'd like to use JCaptcha in a Struts application. I have followed the tutorial and it seems to work fine (smile)

    However, I'd like to use another engine than the default one. I suppose I have to set some properties in the <plug-in className="com.octo.captcha.module.struts.CaptchaServicePlugin"/> declaration...

    In the doc it is written:
    "(there's many settable property available, but none are required, this is detailed in the module documentation)."

    I haven't succeeded to find any detailed documentation about these properties.

    Could any one help me?

    Thanks,

    bruno.schuermans@accenture.com

  2. Basically follow these steps to use another engine in struts:

    1) create a new service class like this:

    package mypackage;
    import com.octo.captcha.engine.image.gimpy.SimpleListImageCaptchaEngine;
    
    import com.octo.captcha.service.image.EhcacheManageableImageCaptchaService;
    
    import com.octo.captcha.service.image.ImageCaptchaService;
    
    public class MyOwnManageableImageCaptchaService extends EhcacheManageableImageCaptchaService
    
    implements ImageCaptchaService {
    
    	public MyOwnManageableImageCaptchaService() {
    		super(new SimpleListImageCaptchaEngine(), 180, 100000);
    	}}
    

    and here pass the wished engine (here SimpleListImageCaptchaEngine which I like best) to the superclass...

    2) in the strus-config.xml pass the new service class to the CaptchaServicePlugin like this:

    <plug-in className="com.octo.captcha.module.struts.CaptchaServicePlugin">
          <set-property property="serviceClass"
              value="mypackage.MyOwnManageableImageCaptchaService" />
      </plug-in>
    
  3. Unknown User (6sic6)

    Hi
    I'm trying to display the tags
    <jcaptcha:question /> and <jcaptcha:message />
    with resource bundle messages.
    I want to change the english messages to Italian messages.
    I don't find the way to do that.
    I found the key for the "question" 'com.octo.captcha.image.gimpy.Gimpy' but not for the 'message'.
    How can I display others message than the default?
    I'm using Struts. I must set some properties under the
    <plug-in className="com.octo.captcha.module.struts.CaptchaServicePlugin"/>
    ?
    thanks for your response
    martina

  4. Hi,

    I tried to implement JCaptcha in my Struts application and it seems to work fine .But this message is appearing in my form "please type the word appearing in the picture" which I don't want .please advise.

    Thanks,
    Aarthy

  5. I`m trying to change de message and the question, but i don´t know how?? The key for the messagge is "jcaptcha_fail" but i put it in my ApplicationResources.propierties and don´t use my message.
    Can anybody help me???

    Thanks

    Calcetos

  6. Is there a way to combine the struts form validation with the Captcha validation?

    Currently it only does one at a time, you can have both done and do all validation in one step.

  7. To customize the messages, look at the CaptchaModuleConfig class.

    Eg, from some place you do initialization, you can call:

    CaptchaModuleConfig.getInstance().setMessageValue( ...)

    And that will customize the error message. Look at the JavaDocs for more details.

  8. I have a Struts project that uses Struts 1.0 is there a version of JCaptcha that uses that version.

  9. I just don't seem to be able to "simply" set my own size (width and height) for my jcaptcha.

    anybody?