ReCAPTCHA Spring Integration

ReCAPTCHA Spring Integration

This demo will show you how to do ReCAPTCHA spring integration.

Below are needed for ReCAPTCHA Spring Integration:

  • Eclipse 3.0 or above (Download eclipse from here)
  • JDK 1.6 or above (Download from here: JDK 1.6)
  • Tomcat 6 or above (Please follow link to install and configure tomcat in eclipse:Configure and Run Tomcat server in eclipse
  • Spring jars which is already included in project for download in the bottom.Below is screen details screen shot:

ReCAPTCHA Spring Integration

 

  • Project structure:

ReCAPTCHA Spring Integration

ReCAPTCHA Spring Integration Step 1:

  • ReCAPTCHA introduction: ReCAPTCHA is inbuilt program which checks if user is human or computer when somebody interacts with the application. You might have seen it before – the colorful images with full distorted image or text in the bottom of some web registration forms. ReCAPTCHAs now days are very popular on many websites which prevent abuse from the automated programs that is usually written to generate spam and ReCAPTCHA create shield on them so no computer automated program could read distorted text as well as humans can.

ReCAPTCHA Spring Integration

ReCAPTCHA Spring Integration Step 2 : You need three value to integrate ReCaptcha to your application:

  • Captcha Service URL : To validate entered text
  • Captcha JS : To include on client page
  • Captcha public key : To include on client page

ReCAPTCHA Spring Integration Step 3 :

ReCAPTCHA Spring Integration Step 4:

  • Now create Spring MVC  dynamic project name : SpringMVCProject ( If you are not sure how to create dynamic project please use this link: Create dynamic project eclipse
  • Create package name : com.bean inside src
  • Create class name RecaptchaBean.java copy paste below code. We are creating bean class with one attribute (captchaError) which we will use to show error on run-time.
package com.bean;

import java.io.Serializable;

public class RecaptchaBean implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String captchaError;
	/**
	 * @return the captchaError
	 */
	public String getCaptchaError() {
		return captchaError;
	}
	/**
	 * @param captchaError the captchaError to set
	 */
	public void setCaptchaError(String captchaError) {
		this.captchaError = captchaError;
	}

}

 

  • Create package com.controller inside src folder
  • Create class name SpringMVCController.java copy paste below code. This is main class to process request and validate the entered data by the users return back page.
package com.controller;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.bean.RecaptchaBean;
import com.util.CaptchaValidator;

@Controller
public class SpringMVCController {

	@Autowired
	private CaptchaValidator captchaValidator;

	@RequestMapping(value="/helloWorld.web",method = RequestMethod.GET)
	public String printWelcome(ModelMap model) {

		model.addAttribute("message", "Google Recaptcha!!!");
		model.addAttribute("captchajs", captchaValidator.getCaptchajs());
		model.addAttribute("captchaPublicKey", captchaValidator.getCaptchaPublicKey());		
		return "helloWorld";

	}

	@RequestMapping(value="/submitCaptcha.web",method = RequestMethod.POST)
	public String submitCaptcha(@ModelAttribute("recaptchaBean") RecaptchaBean recaptchaBean,BindingResult result, ModelMap model, HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		String captchaChallenge = request.getParameter("recaptcha_challenge_field");
		String captchaText = request.getParameter("recaptcha_response_field");		
		List<String> captchErrors = captchaValidator.validate(captchaChallenge, captchaText);			
		if (!captchErrors.isEmpty()){
			recaptchaBean.setCaptchaError(captchErrors.get(0));	
			result.rejectValue("captchaError", captchErrors.get(0));
			model.addAttribute("message", "Google Recaptcha!!!");
			model.addAttribute("captchajs", captchaValidator.getCaptchajs());
			model.addAttribute("captchaPublicKey", captchaValidator.getCaptchaPublicKey());
			return "helloWorld";
		}else {
			model.addAttribute("captchaValue", captchaText);
			model.addAttribute("message", "Successful!!!");
			return "captchaValidateSuccessful";
		}		

	}

}

 

As you could see controller class has two method: First operation is to show welcome page to the user and second operation is to validate submitted ReCAPTCHA Spring Integration.

  • Create package name: com.util inside src folder.
  • Create class name: CaptchaValidator.java inside package com.util and copy paste below content:
package com.util;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;

@Component
public class CaptchaValidator {

	private String captchaService;
	private String captchaPublicKey;
	private String captchajs;

    private static final Integer TIMEOUT = 5000; // 5 seconds
    private static final Integer MAX_CONNECTIONS = 10;

    private final HttpClient httpClient = new HttpClient(new MultiThreadedHttpConnectionManager());
    private URL captchaServiceURL;

    public void init() throws MalformedURLException  {
        httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(TIMEOUT);
        httpClient.getHttpConnectionManager().getParams().setSoTimeout(TIMEOUT);
        httpClient.getHttpConnectionManager().getParams().setMaxTotalConnections(MAX_CONNECTIONS);
        captchaServiceURL = new URL(captchaService);
    }   

    public List<String> validate(String captchaChallenge, String captchaText) throws Exception {
    	List<String> errors = new ArrayList<String>();

        if (StringUtils.isBlank(captchaText)) {
            errors.add("NotBlank.captcha.response");
            return errors;
        }

        NameValuePair[] nameValuePairs = new NameValuePair[5];
        nameValuePairs[0] = new NameValuePair("public_key", captchaPublicKey);
        nameValuePairs[1] = new NameValuePair("client_ip_address","");
        nameValuePairs[2] = new NameValuePair("challenge_token",captchaChallenge);
        nameValuePairs[3] = new NameValuePair("user_answer", captchaText);
        nameValuePairs[4] = new NameValuePair("json", "false");

        HttpMethod method = new GetMethod(captchaServiceURL.toString());

        method.setQueryString(nameValuePairs);

        String response = "";
        try {
            int returnCode = httpClient.executeMethod(method);
            if (returnCode == HttpStatus.SC_OK) {
                response = method.getResponseBodyAsString();
            } else {
               System.out.println("CAPTCHA Service returned HttpStatus Code: " + returnCode);
            }
        } catch (Exception e) {
           System.out.println("Exception when invoking CAPTCHA Service"+e);
        } finally {
            method.releaseConnection();
            // Closes idle connections
            httpClient.getHttpConnectionManager().closeIdleConnections(0L);
        }

        // Parse response
        String lines[] = response.split("\\r?\\n");
        if (lines[0].equalsIgnoreCase("true")) {
            return Collections.emptyList();
        } else {
            String error = lines[1];
            if (error.equalsIgnoreCase("invalid-key")) {
                System.out.println("The CAPTCHA Service public key is incorrect.");
                errors.add(error);
            } else if (error.equalsIgnoreCase("invalid-parameters")) {
               System.out.println("The CAPTCHA Service was invoked with incorrect parameters.");
               errors.add(error);
            } else if (error.equalsIgnoreCase("unknown-error")) {
               System.out.println("The CAPTCHA Service returned an unknown error.");
               errors.add(error);
            } else if (error.equalsIgnoreCase("incorrect-captcha-sol")) {
                System.out.println("The letters in the graphic were entered incorrectly. Please try again.");
                errors.add(error);
             } else {
                errors.add(error);
            }                        
        }

        return errors;
    }

	/**
	 * @return the captchaService
	 */
	public String getCaptchaService() {
		return captchaService;
	}

	/**
	 * @param captchaService the captchaService to set
	 */
	public void setCaptchaService(String captchaService) {
		this.captchaService = captchaService;
	}

	/**
	 * @return the captchaPublicKey
	 */
	public String getCaptchaPublicKey() {
		return captchaPublicKey;
	}

	/**
	 * @param captchaPublicKey the captchaPublicKey to set
	 */
	public void setCaptchaPublicKey(String captchaPublicKey) {
		this.captchaPublicKey = captchaPublicKey;
	}

	/**
	 * @return the captchaServiceURL
	 */
	public URL getCaptchaServiceURL() {
		return captchaServiceURL;
	}

	/**
	 * @param captchaServiceURL the captchaServiceURL to set
	 */
	public void setCaptchaServiceURL(URL captchaServiceURL) {
		this.captchaServiceURL = captchaServiceURL;
	}

	/**
	 * @return the captchajs
	 */
	public String getCaptchajs() {
		return captchajs;
	}

	/**
	 * @param captchajs the captchajs to set
	 */
	public void setCaptchajs(String captchajs) {
		this.captchajs = captchajs;
	}

}

 

  • Create resources folder inside Java Resources. To create right click project –> Click New –> Click Source folder and name it resources. We are creating this folder to keep properties file in it which will be included in classpath automatically by eclipse. We will use properties value at run-time.
  • Create folder name captcha inside resources folder
  • Create XML file name Captcha.properties and copy paste below content in it:
captcha_service=http://enter your service url
captcha_js=https://your server/captcha_script.jsp
captcha_public_key=your public key

 

  • Create messages.properties file inside resources folder and copy paste below content in it:
invalid-key=The CAPTCHA Service public key is incorrect.
invalid-parameters=The CAPTCHA Service was invoked with incorrect parameters.
unknown-error=The CAPTCHA Service returned an unknown error.
incorrect-captcha-sol=The letters in the graphic were entered incorrectly. Please try again.
NotBlank.captcha.response=The letters in the graphic were entered incorrectly. Please try again.

 

ReCAPTCHA Spring Integration Step 5 :

  • Create jsp folder inside WebContent\WEB-INF\
  • Create jsp file name captchaValidateSuccessful.jsp inside \WebContent\WEB-INF\jsp\ and copy paste below content in it:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt" prefix="fmt"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Spring 3 MVC ReCAPTCHA</title>
<style type="text/css">
.captchaError{color: #ff0000;font-size: 14px;height: 3px;font-weight: bold;}
</style>
</head>
<body>
<form:form commandName="recaptchaBean" method="post" name="recaptchaBean" action="submitCaptcha.web"> 
<h1>Recaptcha spring demo: ${message}<br><br>

Value you entered: ${captchaValue}</h1>

<br>

</form:form>
</body>
</html>

 

  • Create jsp file name helloWorld.jsp inside \WebContent\WEB-INF\jsp\ and copy paste below content in it:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt" prefix="fmt"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Spring 3 MVC ReCAPTCHA</title>
<style type="text/css">
.captchaError{color: #ff0000;font-size: 14px;height: 3px;font-weight: bold;}
</style>
</head>
<body>
<form:form commandName="recaptchaBean" method="post" name="recaptchaBean" action="submitCaptcha.web"> 
<h1>Recaptcha spring demo: ${message}</h1>

<table>
	<tr>
      <td class="intro_text" align="middle">
      <span style="align:center"><form:errors path="captchaError" class="captchaError"/><br><br></span>          
     </td>
    </tr>
  	<tr>
      	<td class="captcha_text">Please enter the characters you see in the box below (not case-sensitive):</td>
   	</tr>
   	<tr>
      	<td>
      	  	<script type="text/javascript" src='${captchajs}?theme=clean&key=${captchaPublicKey}'></script>              
   		</td>
     </tr>              
</table>
<br>
<input type="submit" value="Submit">
</form:form>
</body>
</html>

 

ReCAPTCHA Spring Integration Step 6 :

  • Create class XML file name dispatcher-servlet.xml inside WebContent\WEB-INF\ folder and copy paste below content in it:
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans     
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">

	<context:component-scan base-package="com.controller" />

	<mvc:annotation-driven />

     <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>                
                <value>classpath:/captcha/Captcha.properties</value>
                <value>classpath:messages.properties</value>
            </list>
        </property>
    </bean>

	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix">
			<value>/WEB-INF/jsp/</value>
		</property>
		<property name="suffix">
			<value>.jsp</value>
		</property>
	</bean>

	<!-- bind your messages.properties -->
	<bean class="org.springframework.context.support.ResourceBundleMessageSource"
		id="messageSource">
		<property name="basename" value="messages" />
	</bean>

	<bean id="captchaValidator" class="com.util.CaptchaValidator" init-method="init">
        <property name="captchaService" value="${captcha_service}"/>
        <property name="captchajs" value="${captcha_js}"/>
        <property name="captchaPublicKey" value="${captcha_public_key}"/>
    </bean>

</beans>

 

  • We already have web.xml file created during dynamic project. Copy paste below content in it:
<?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">
	<servlet>
		<servlet-name>dispatcher</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>dispatcher</servlet-name>
		<url-pattern>*.web</url-pattern>
	</servlet-mapping>

	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
	</context-param>

	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener> 

	<welcome-file-list>	 
	   <welcome-file>helloWorld.web</welcome-file>
	</welcome-file-list>

</web-app>

 

Important: Don’t forget to replace below with your configuration in Captcha.properties file. 

ReCAPTCHA Spring Integration Step 7 :

  • We have completed all our configuration and coding now its time to run the application to see the output
  • Now refresh and clean your prouct
  • To run application: Right click project –> Run As –> Run on Server. You will see below welcome page with ReCAPTCHA.

ReCAPTCHA Spring Integration

  • In this page enter some wrong value and click submit button. You will see same page with validation error in red below. It means our validation went successful.

ReCAPTCHA Spring Integration

 

  • Now enter same value as you see in ReCAPTCHA box and click Submit button. You will validation came successful with new page. It will show you successful message and the text you entered as below:

ReCAPTCHA Spring Integration

ReCAPTCHA Spring Integration

  • That’s it.

ReCAPTCHA Spring Integration Download full project: SpringMVCProject

5 thoughts on “ReCAPTCHA Spring Integration

      • I create Get reCAPTCHA as below:
        Domain Name: localhost
        Public Key: XXXXXXXXXXXXXXXXXXXXXX

        I download your example SpringMVCProject I configure Captcha.properties as below :-
        captcha_service=http://localhost:8080/
        captcha_js=http://localhost:8080/SpringMVCProject/helloWorld.web
        captcha_public_key=as I revived from Get reCAPTCHA

        is this steps correct or not ?

Leave a Reply

Your email address will not be published. Required fields are marked *