Archive

Archive for the ‘Solutions Log’ Category

10 Minute Guide to Spring Web Services

October 5th, 2012 1 comment

Spring Web Services simplifies creation of contract-first SOAP based web services. In this blog post, I will create a hello world web service using Spring Web Services. The service will take a string as a parameter, prepends “Hello ” and returns it. Here are the steps for creating the service:

1. We start by creating a maven based web project. Spring Web Services provides an archetype that can be used to simplify creation of web service project.

2. Add Spring Web Services and its dependent jars to the project. Here is the maven dependency that you need to add:

	
	 <dependencies>
        <dependency>
            <groupId>org.springframework.ws</groupId>
            <artifactId>spring-ws-core</artifactId>
            <version>2.1.0.RELEASE</version>
        </dependency>
    </dependencies>
	
	

3. Since we are developing contract first web service, we create a data contract that defines the input and output messages the service accepts. Create a helloworld.xsd file under WEB-INF folder with the following content:

	
	<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="qualified"
        targetNamespace="http://blog.inflinx.com/ws/helloworld"
        xmlns:tns="http://blog.inflinx.com/ws/helloworld">

     <element name="helloworldRequest" type="string"/>

    <element name="helloworldResponse" type="string"/>
</schema>
	
	

4. The next step is to create an Endpoint that handles incoming XML messages. Here is the HelloWorldEndpoint implementing hello world service:

package com.inflinx.blog.helloworld;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
import org.springframework.ws.server.endpoint.annotation.RequestPayload;
import org.springframework.ws.server.endpoint.annotation.ResponsePayload;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;

@Endpoint
public class HelloWorldEndpoint {
	
	 private static final String NAMESPACE_URI = "http://blog.inflinx.com/ws/helloworld";
	
	 private static final String REQUEST_LOCAL_NAME = "helloworldRequest";
	 
	 private static final String RESPONSE_LOCAL_NAME = "helloworldResponse";
	 
	 
	 @PayloadRoot(localPart = REQUEST_LOCAL_NAME, namespace = NAMESPACE_URI)
	 @ResponsePayload
	 public Element handleRequest(@RequestPayload Element requestElement) throws Exception {
		 
		 // Get the submitted text value
		 String text = requestElement.getChildNodes().item(0).getNodeValue();
		 
		 System.out.println("Request Pay Load: " + text);
		 
		 // Create a response Element
		 DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
		 DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
	     Document document = documentBuilder.newDocument();
	     Element responseElement = document.createElementNS(NAMESPACE_URI, RESPONSE_LOCAL_NAME);
	     Text responseText = document.createTextNode("Hello "+ text);
	     responseElement.appendChild(responseText);
		 
		 return responseElement;
	 }
}

As you can see, the class is annotated with @EndPoint enabling it for component scanning. The @PayloadRoot annotation tells Spring that handleRequest method can handle XML messages. The method implementation is self explanatory: we get the submitted text, create a new response element and return the text with Hello prepended.

5. The next step is to add a Spring Web Service MessageDispatcherServlet to web.xml and map all the incoming requests to it. Here is the modified web.xml file:


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

    <display-name>Hello World Web Service</display-name>

    <servlet>
        <servlet-name>spring-ws</servlet-name>
        <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
        <init-param>
            <param-name>transformWsdlLocations</param-name>
            <param-value>true</param-value>
        </init-param>
    </servlet>
	
    <servlet-mapping>
        <servlet-name>spring-ws</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

</web-app>

6. The MessageDispatcherServlet is named spring-ws. Hence the servlet will look for a Spring configuration file named spring-ws-servlet.xml under WEB-INF folder. Here is the spring-ws-servlet.xml file:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:sws="http://www.springframework.org/schema/web-services"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
	
	<context:component-scan base-package="com.inflinx.blog.helloworld"/>
	
    <sws:annotation-driven/>

	 <sws:dynamic-wsdl id="helloworld" portTypeName="helloworld" locationUri="http://localhost:8080/hello-world">
        <sws:xsd location="/WEB-INF/helloworld.xsd"/>
    </sws:dynamic-wsdl>

</beans>

The dynamic-wsdl element generates a WSDL automatically for the web service.

7. Deploy the application to a container such as Tomcat or Glassfish. Once deployed, the WSDL can be accessed using the URL: http://localhost:8080/helloworld/helloworld.wsdl

8. Finally, using SOAP UI submit the following request:


<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:hel="http://blog.inflinx.com/ws/helloworld">
   <soapenv:Header/>
   <soapenv:Body>
      <hel:helloworldRequest>World</hel:helloworldRequest>
   </soapenv:Body>
</soapenv:Envelope>

You should see the following response from the service:


<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header/>
   <SOAP-ENV:Body>
      <helloworldResponse xmlns="http://blog.inflinx.com/ws/helloworld">Hello World</helloworldResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Introduction to Spring Data JPA

September 15th, 2012 8 comments

The Spring Data JPA, a sub project of Spring Data is aimed at simplifying repository implementations. Repositories typically provide Create, Read, Update and Delete (CRUD) operations for domain objects. In this blog post, I will show how Spring Data JPA drastically reduces the effort needed to create repositories.

We will be using HSQLDB as the database and Hibernate as the JPA implementation provider. Here is a complete list project’s dependencies from Maven’s pom.xml file:


	<dependencies>	
		 <dependency>
			 <groupId>org.springframework.data</groupId>
	 		 <artifactId>spring-data-jpa</artifactId>
	 		 <version>1.1.0.RELEASE</version>
	 		 <exclusions>
	 		 	<exclusion>
					<groupId>org.slf4j</groupId>
					<artifactId>jcl-over-slf4j</artifactId>	 		 	
	 		 	</exclusion>
	 		 	</exclusions>
		</dependency>
		
		<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
			<version>1.1.1</version>
		</dependency>
		
		<dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib-nodep</artifactId>
			<version>2.1_3</version>
		</dependency>
		
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.14</version>
		</dependency>
		
		<dependency>
			<groupId>aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.5.2a</version>
		</dependency>
		
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>3.1.2.RELEASE</version>
			<scope>test</scope>
		</dependency>
		
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-entitymanager</artifactId>
			<version>4.1.0.Final</version>
		</dependency>
		
		<dependency>
			<groupId>org.hsqldb</groupId>
			<artifactId>hsqldb</artifactId>
			<version>2.2.8</version>
		</dependency>
		
	</dependencies>

Before we go about implementing repositories using Spring Data JPA, let’s create two domain objects Person and Address:


package com.inflinx.blog.springdata.domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="PERSON")
public class Person {

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="PERSON_ID")
	private Long id;

	@Column(name="FIRST_NAME")
	private String firstName;
	
	@Column(name="LAST_NAME")
	private String lastName;
	
	@Column(name="GENDER_CODE")
	private String genderCode;
		
	// Getters and Setters	
}

package com.inflinx.blog.springdata.domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name="ADDRESS")
public class Address {
	
	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="ADDRESS_ID")
	private int id;

	@Column(name="STREET")
	private String street;
	
	@Column(name="CITY")
	private String city;
	
	@Column(name="STATE")
	private String state;

	@Column(name="ZIPCODE")
	private int zipCode;
	
	@ManyToOne
	@JoinColumn(name="PERSON_ID")
	private Person person;
	
	// Getters and Setters
}	
	

Notice that the two domain classes have JPA annotations such as @Table and @Column that map these classes to relational tables. Also notice the Many To One relationship between Address and Person classes.

Simple JPA Repository

We now start by creating a Spring Data JPA repository for the Person class. This involves creating a repository interface as shown below. The PersonRepository interface extends the Spring Data JPA’s Repository marker interface and has one finder method. The findOne method follows Spring Data JPA’s naming convention for retrieving an entity using its ID.

package com.inflinx.blog.springdata.repository;

import org.springframework.data.repository.Repository;
import com.inflinx.blog.springdata.domain.Person;

public interface PersonRepository extends Repository < Person, Long > {
	public Person findOne(Long id);
}

Traditionally, we would also create an implementation class for this repository. However Spring Data JPA alleviates this need and provides an implementation class (proxy) automatically at runtime. For this to happen, we add the jpa:repositories bean declaration to our context file. Here is the complete context file:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:jdbc="http://www.springframework.org/schema/jdbc"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:repository="http://www.springframework.org/schema/data/repository"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
		http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.1.xsd
		http://www.springframework.org/schema/data/repository http://www.springframework.org/schema/data/repository/spring-repository-1.0.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
	
	<jdbc:embedded-database id="dataSource">
        <jdbc:script location="classpath:schema.sql"/>
        <jdbc:script location="classpath:test-data.sql"/>
    </jdbc:embedded-database>
    
	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" 
          p:data-source-ref="dataSource" p:persistence-xml-location="classpath:test-persistence.xml" p:jpaDialect-ref="jpaDialect">
    </bean>
    
    <tx:annotation-driven transaction-manager="transactionManager"/>  
       
	<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
	
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" 
          p:entity-manager-factory-ref="entityManagerFactory">
    </bean>
    
    <jpa:repositories base-package="com.inflinx.blog.springdata.repository" />
</beans>

The jdbc:embedded-database tag in the context file starts an in-memory database using HSQLDB and creates a datasource for it. The schema.sql file shown below has the DDL commands for creating the Person and Address table:

CREATE TABLE PERSON (PERSON_ID INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, 
					FIRST_NAME VARCHAR(256), 
					LAST_NAME VARCHAR(256), 
					GENDER_CODE VARCHAR(1));

CREATE TABLE ADDRESS(ADDRESS_ID INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, 
 					STREET VARCHAR(256), 
 					CITY VARCHAR(100), 
 					STATE VARCHAR(10), 
 					ZIPCODE INT,
 					PERSON_ID INT,
 					FOREIGN KEY (PERSON_ID) REFERENCES PERSON(PERSON_ID)); 

The test-data.sql file has the test data we will be using to test our repositories:

	INSERT INTO PERSON (FIRST_NAME, LAST_NAME, GENDER_CODE) VALUES ('John', 'Doe', 'M');
	INSERT INTO PERSON (FIRST_NAME, LAST_NAME, GENDER_CODE) VALUES ('Jane', 'Doe', 'F');
	INSERT INTO PERSON (FIRST_NAME, LAST_NAME, GENDER_CODE) VALUES ('Joe', 'Bloggs', 'M');

The entitiyManagerFactory bean uses test-persistence.xml file that has the standard JPA configuration.


<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0">

  <persistence-unit name="springdata" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    
    <class>com.inflinx.blog.springdata.domain.Person</class>
    <class>com.inflinx.blog.springdata.domain.Address</class>
    
    <properties>
      <property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver"/>
      <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
      <property name="hibernate.hbm2ddl.auto" value="update"/>
	  <property name="hibernate.show_sql" value="true"/>
	  <property name="hibernate.format_sql" value="true"/>
    </properties>
  </persistence-unit>
</persistence>

This completes all the setup needed for creating a Spring Data JPA repository. Now let’s create a JUnit test class to test our implementation.


package com.inflinx.blog.springdata.repository;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
import org.springframework.transaction.annotation.Transactional;

import com.inflinx.blog.springdata.domain.Person;

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class, TransactionalTestExecutionListener.class})
@Transactional
@ContextConfiguration(locations = {"classpath:test-context.xml"})
public class PersonRepositoryTest {

	@Autowired
	private PersonRepository personRepository;
	
	@Test
	public void testPerson() {
		Person person = personRepository.findOne(1L);
		Assert.assertNotNull(person);
		System.out.println("First Name: " + person.getFirstName());
	}
	
}

Notice that we are simply injecting the PersonRepository implementation into the test. When you run the class, you should see that test has passed and “First Name: Jane” in your console.

CRUD JPA Repository

The above PersonRepository has only one finder method and might not be ideal for most real world cases. To address this, Spring Data JPA provides an aptly named CrudRepository interface that extends Repository interface and adds persistence, finder and delete methods. The table below lists some of the available CrudRepository methods:

save(S entity) Saves a given entity
save(Iterable entities) Saves all the given entities
findOne(ID id) Retrieves an entity by its id
exists(ID id) Checks if a given entity exists
findAll Returns all the entities
count Returns the number of all the entities
delete(ID id) Deletes an entity with the given id
delete(T entity) Delets a given entity

A new person repository interface that uses CrudRepository is given below.


package com.inflinx.blog.springdata.repository;

import org.springframework.data.repository.CrudRepository;

import com.inflinx.blog.springdata.domain.Person;

public interface PersonCrudRepository extends CrudRepository < Person, Long > {

}

Here is a JUnit test that tests the above repository:


package com.inflinx.blog.springdata.repository;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.transaction.annotation.Transactional;

import com.inflinx.blog.springdata.domain.Person;

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class})
@Transactional
@ContextConfiguration(locations = {"classpath:test-context.xml"})
public class PersonCrudRepositoryTest {

	@Autowired
	private PersonCrudRepository personRepository;
	
	@Test
	@Rollback(false)
	public void testCreate() {
		Person p = new Person();
		p.setFirstName("Test");
		p.setLastName("Data");
		p.setGenderCode("M");
		
		p = personRepository.save(p);
		Assert.assertNotNull(p.getId());
		System.out.println("Created Id: " + p.getId());
	}	
}

Custom Finder Methods

Spring Data JPA makes it very easy to add new finder methods to repositories. For example, let’s say we want to retrieve all persons with a given last name. Here is the modified PersonCrudRepository repository with the new finder method:

package com.inflinx.blog.springdata.repository;

import java.util.List;
import org.springframework.data.repository.CrudRepository;
import com.inflinx.blog.springdata.domain.Person;

public interface PersonCrudRepository extends CrudRepository < Person, Long > {

	public List< Person > findByLastName(String lastName);
}

The convention for these finder methods is simply findByMemberName. It is also possible to combine multiple members into one finder method. So, findByLastNameAndFirstName(String lastName, String firstName) will find all persons with the given first name and last name.

Here is the JUnit test class to test the findByLastName method:

 

	@Test
	public void testFindByLastName() {
		
		List< Person > lastNameList = personRepository.findByLastName("Doe");
		Assert.assertEquals(2, lastNameList.size());
	}

Named Queries

The out of the box CRUD methods are sufficient for most cases. However, there are times where we might want to execute custom SQL Queries to retrieve data. For example, let’s say we want to count all the persons that have a given last name. To address such situations, Spring Data JPA provides a @Query annotation. Here is the new person repository with the @Query annotated method:

package com.inflinx.blog.springdata.repository;

import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;

import com.inflinx.blog.springdata.domain.Person;

public interface PersonCrudRepository extends CrudRepository < Person, Long > {

	@Query("select count(p) from Person p where p.lastName = ?1")
	public Long getLastNameCount(String lastName);
	
}

Here is a test method for the above Query method:

	@Test
	public void testGetLastNameCount() {
		
		Long count = personRepository.getLastNameCount("Doe");
		Assert.assertEquals(2L, count.longValue());
	}

Custom Repository Implementation

For cases, where the out of the box repository implementations are not enough, Spring Data JPA makes it easy to provide custom implementations that would still integrate with the generic repository abstraction. To see this in action, let’s implement a custom Address repository. We start with a custom interface that declares the additional functionality.

package com.inflinx.blog.springdata.repository;

public interface AddressRepositoryCustom {
	
	public Long someRandomMethod();
	
}

The next step is to create a class that implements the custom functionality.

package com.inflinx.blog.springdata.repository.jpa;

import com.inflinx.blog.springdata.repository.AddressRepositoryCustom;

public class AddressRepositoryImpl implements AddressRepositoryCustom {

	public Long someRandomMethod() {
		return 143L;
	}
}

Finally, we create the AddressRepository interface that extends the custom interface as shown below:

public interface AddressRepository extends CrudRepository < Address, Long >, AddressRepositoryCustom {
	
}

Here is a test class that tests the custom method implementation:

package com.inflinx.blog.springdata.repository;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.transaction.annotation.Transactional;

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class})
@Transactional
@ContextConfiguration(locations = {"classpath:test-context.xml"})
public class AddressRepositoryCustomTest {
	
	@Autowired
	private AddressRepository personRepository;
	
	@Test
	public void testSomeMethod() {
		
		Assert.assertEquals(143L, personRepository.someRandomMethod().longValue());
	}
	
}

Spring Data JPA requires that you follow strict naming conventions when creating custom repository implementation (unless you provide additional configuration). For example, if the repository interface is AddressRepository, then the name of the custom interface should be AddressRepositoryCustom. If you don’t follow this convention, you will end up with errors similar to this:

Caused by: java.lang.IllegalArgumentException: Could not create query metamodel for method public abstract java.lang.Long com.inflinx.blog.springdata.repository.AddressRepositoryCustom.someRandomMethod()!
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:92)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:162)

Integrating CAPTCHA Into Spring MVC Web Applications

May 25th, 2012 1 comment

Integrating CAPTCHA in an application involves two simple steps:

  1. Display CAPTCHA Widget
  2. Validate CAPTCHA Reponse

In this blog post, I will be using Google’s reCAPTCHA. Before we can start using reCAPTCHA, we need to sign up for API keys.

Obtaining reCAPTCHA keys

1. Go to the reCAPTCHA Key Signup Page and login using your Google Account.

Enter the your domain name and hit “Create Key”. The generated keys by default are restricted to the specified domain. However, all keys will work on the localhost domain, making it easy to test during development.

Captcha Creation



Make a note of the generated public and private keys. We need both keys in order to generate CAPTCHA and verify response.

Display CAPTCHA Widget

reCAPTCHA provides a Java Library wrapper that makes CAPTCHA generation/verification easier. Maven users can get the jar file with the following dependency:

   <dependency>
		<groupId>net.tanesha.recaptcha4j</groupId>
		<artifactId>recaptcha4j</artifactId>
		<version>0.0.7</version>
	</dependency>

With the dependency added, generating the CAPTCHA Widget simply involves placing the below scriptlet in a JSP page:

	<%
		ReCaptcha captcha = ReCaptchaFactory.newReCaptcha("PUBLIC_KEY", "PRIVATE_KEY", false);
		out.print(captcha.createRecaptchaHtml(null, null));
    %>	

In the above code, we first create an instance of ReCaptcha by passing in the generated public and private key. The third parameter instructs if a noscript tag should to be placed around the generated HTML.

Since, I don’t like using Scriptlets in my JSP pages, I will create a reusable JSP tag that wraps the above code. We start out by creating a CaptchaTag class as shown below:


package com.inflinx.blog.web.tag;

import java.io.IOException;
import java.util.Properties;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

import org.apache.commons.lang.StringUtils;

import net.tanesha.recaptcha.ReCaptcha;
import net.tanesha.recaptcha.ReCaptchaFactory;

public class CaptchaTag extends SimpleTagSupport
{
	private String publickey;
	private String privatekey;
	private String themeName;
	
	@Override
	public void doTag() throws JspException, IOException 
	{
		ReCaptcha captcha = ReCaptchaFactory.newReCaptcha(publickey, privatekey, false);
		Properties properties = new Properties();
		
		if(StringUtils.isNotEmpty(themeName))
		{
			properties.put("theme", themeName);
		}
		
		String captchaHtml = captcha.createRecaptchaHtml(null, properties);
		getJspContext().getOut().write(captchaHtml);
	}

	public String getThemeName() {
		return themeName;
	}

	public void setThemeName(String themeName) {
		this.themeName = themeName;
	}

	public String getPublickey() {
		return publickey;
	}

	public void setPublickey(String publickey) {
		this.publickey = publickey;
	}

	public String getPrivatekey() {
		return privatekey;
	}

	public void setPrivatekey(String privatekey) {
		this.privatekey = privatekey;
	}
}

The above tag takes has three attributes: public key, private key and theme name. The theme option can be used to control the reCAPTCHA widget’s look and feel. Possible values include: “red”, “white”, “blackglass” or “clean”. The default is the red.

To complete the implementation of the tag, lets create a captcha.tld file under WEB-INF/tlds folder with the following contents:

<taglib xsi:schemaLocation="http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.1">
     
    <tlibversion>1.0</tlibversion>
    <jspversion>2.1</jspversion>
    <shortname>CaptcahTags</shortname>
    <uri>http://blog.inflinx.com</uri>
    <info>Captcha Tags</info>
 
    <tag>
        <name>captcha</name>
        <tagclass>com.inflinx.blog.web.tag.CaptchaTag</tagclass>
        <bodycontent>empty</bodycontent>
        <info>Generates Captcha Widget</info>
        <attribute>
             <name>publickey</name>
             <required>true</required>
			 <rtexprvalue>true</rtexprvalue> 
        </attribute>
		<attribute>
             <name>privatekey</name>
             <required>true</required>
			 <rtexprvalue>true</rtexprvalue> 
        </attribute>
		<attribute>
             <name>themeName</name>
             <required>false</required>
			 <rtexprvalue>true</rtexprvalue> 
        </attribute>
    </tag>
 
</taglib>

With all this in place, update the JSP page with the following code to display the CAPTCHA Widget:


<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%@ taglib prefix="captcha" uri="/WEB-INF/tlds/captcha.tld" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>

<html>
<head>
	<title>Home</title>
</head>
<body>

<form method="post">

	<captcha:captcha themeName="clean" publickey="YOUR_PUBLIC_KEY" privatekey="YOUR_PRIVATE_KEY"/>
	
</form>


</body>
</html>

Upon running the code, you should see a CAPTCHA similar to the image below:

Captcha In Action

Validate CAPTCHA Reponse

In order to valdiate the CAPTCHA response, we need to modify the POST method of the receiving controller as shown below:

@RequestMapping(method = RequestMethod.POST)
	public String processSubmit(HttpServletRequest request, Model model)
	{
		ReCaptchaImpl reCaptcha = new ReCaptchaImpl();
        reCaptcha.setPrivateKey("YOUR_PRIVATE_KEY");
        
		String remoteAddr = request.getRemoteAddr();
        String challengeField = request.getParameter("recaptcha_challenge_field");
        String responseField = request.getParameter("recaptcha_response_field");
        ReCaptchaResponse reCaptchaResponse = reCaptcha.checkAnswer(remoteAddr, challengeField, responseField);

        if(!reCaptchaResponse.isValid())
        {
        	model.addAttribute("invalidCaptcha", "Captcha Is Invalid");
        	return "home";
        }
        
        return "success";
	}

In the above code, we start by creating a ReCaptchaImpl instance and pass in the Private key. The reCaptcha widget generates two fields “recaptcha_challenge_field”, “recaptcha_response_field” that are needed to verify the response. We pass in those two fields along with the IP Address of the client to get a response.

For invalid responses, we set a model attribute to indicate the error. Now, in a Spring MVC application where you are using a command object for the form, you can add an error instance instead:

		if(!reCaptchaResponse.isValid())
        {
        	errors.reject("captcha.invalid");
        }

Obtaining/Redeeming App Store Promo Codes

April 26th, 2012 No comments

My new iPhone app JEE Interview Questions went on sale today.

JEE Interview Questions App

I needed to get some promo codes and thought it would be a good idea to log the process of obtaining and redeeming promo codes. Before we get any further it is important to remember that Apple only gives out fifty codes for each application. These codes are strictly for non-commercial use only and will expire in 28 days.

Obtaining Promo Codes

In order to obtain the promo code for your app, start by logging into iTunes Connect. Then hit Manage Your Applications.
Manage Apps

On the Application Details page, click the “View Details” button for the version you are interested in.
App Details

The ensuing Page click the “Promo Codes” button.
Promo Codes Link

Then, enter the number of codes you would like and hit Continue. You will be asked to accept Apple’s contract.


The next page will contain a Download button that will allow you to download the promo codes in a text file.
Download Promo Codes

Redeeming Promo Codes

To redeem a promo code, you need to launch the iTunes application on your Mac or Windows. On the top right corner of the iTunes Store, click the “Redeem” link.
Redeem Code

On the next screen, enter the promo code. You might be asked to login. Then, you will see a success screen and your app will get automatically downloaded.
Redeem Success

One way to get the app is to launch the App Store app on your iPhone. Go to Updates -> Purchased -> “Not On This iPhone” and you will see your app waiting to be installed.
JEE Interview Questions - Not Purchased

Categories: iPhone, Solutions Log Tags: , ,

Custom JSR 303 Constraints

April 24th, 2012 No comments

In my previous blog post I talked about validating Spring Web applications using JSR 303 annotations. In that post, we used the out of the box JSR 303 constraints such as @NotEmpty and @Size. These out of the box constraints should be sufficient for most cases. However, there will be situations where you want to develop custom constraints. In this post, we will look at creating a custom constraint
that validates the ISBN number of a book in our Online Bookstore Admin application.

Each JSR 303 validation constraint consists of two parts. The first part is the constraint annotation itself.

package com.inflinx.blog.bookstore.constraint;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.validation.Constraint;
import javax.validation.Payload;

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy=IsbnValidator.class)
public @interface Isbn 
{
	String message() default "{Isbn.message}";

	Class[] groups() default {};

	Class[] payload() default {};
}

The JSR 303 specification requires each constraint annotation to define the following three attributes:

  • message – The error message that gets returned upon validation failure. Here we have defined the default value Isbn.message that acts as a resource bundle key. It is possible to just hard code a message by simply omitting the braces.
  • groups – This defines the constraint groups that this annotation needs to be associated with. Here we will use the default group.
  • Payload – This holds the additional metadata information that can be supplied by validation clients. Here we are using the default empty array.

The @Target, @Retention and @Documented annotations are needed for the annotation declaration. The @Constraint annotation declares the validator that we will be using to validate elements annotated with @Isbn constraint.

The next step in creating the custom constraint is defining the validator.

package com.inflinx.blog.bookstore.constraint;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

import org.apache.commons.validator.routines.ISBNValidator;

public class IsbnValidator implements ConstraintValidator
{
	@Override
	public void initialize(Isbn isbn) { }

	@Override
	public boolean isValid(String value, ConstraintValidatorContext validatorContext) 
	{
		if(value == null || "".equals(value))
		{
			return true;
		}
		else
		{
			return ISBNValidator.getInstance().isValid(value);
		}
	}

}

Every constraint validator needs to implement the ConstraintValidator interface. The actual implementation of the IsbnValidator is straightforward. According to the specification, if the annotated element’s value is null or empty the validation should succeed. If you don’t want a null value, the element should be annotated with @NotNull annotation. The actual validation of the ISBN value is delegated to the Apache Validation API.

Now that we have the constraint defined, the next step is to use it in our Book Store application. To do that, we start out by creating a new property in the Book domain class and annotated it with @Isbn annotation. Here is the modified book class:

package com.inflinx.blog.bookstore.domain;

import javax.validation.constraints.Size;

import org.hibernate.validator.constraints.NotEmpty;

import com.inflinx.blog.bookstore.constraint.Isbn;

public class Book
{
	@NotEmpty
	private String name;
	
	@Size(min=1, max=50)
	private String description;
	
	@NotEmpty
	@Isbn
	private String isbn;
	
	public String getIsbn() {
		return isbn;
	}
	public void setIsbn(String isbn) {
		this.isbn = isbn;
	}
	public String getName()
	{
		return name;
	}
	public void setName(String name)
	{
		this.name = name;
	}
	public String getDescription()
	{
		return description;
	}
	public void setDescription(String description)
	{
		this.description = description;
	}
	
	@Override
	public String toString()
	{
		return "Name: " + name + ", Description: " + description + ", ISBN: " + isbn;
	}
}

Then we need to modify the form.jsp file to add the ISBN form field.

 		<form:form method="post" action="book.html" commandName="book">
					<table>
						<tr>
							<td>Name:</td> <td><form:input path="name" /></td> <td><form:errors path="name" /></td>
						</tr>
						<tr>
							<td>Description:</td> <td><form:textarea path="description"/></td> <td><form:errors path="description" /></td>
						</tr>
						<tr>
							<td>ISBN:</td> <td><form:input path="isbn" /></td> <td><form:errors path="isbn" /></td>
						</tr>
						</table>
					<input type="submit" value="Create" />
		</form:form>

The final step in this process is to add a new validation key/value to the messages.properties file. Here is the new messages.properties file:

NotEmpty.book.name=Name is a required field
Size.book.description=Description must be between 1 and 50 characters
Isbn.book.isbn=Please enter a valid ISBN

Now, when you submit the form with an invalid ISBN value, you will see a validation error.

Getting Started With Git and GitHub

April 22nd, 2012 No comments

For the last two years, I have been using Git on a windows machine. Recently, I had to install Git on my Mac and connect to Github. Since I have not blogged for such a long time, I thought of jotting down my notes here.

Setting Up Git Locally

1. The first step in this process is to download and install Git locally. The easiest way to do is to download the Git OS X installer from http://code.google.com/p/git-osx-installer/downloads/list The recent version at the time of writing is 1.7.9.4.

Once the download is complete, just run the installer. Upon successful installation, run the following command:

2. The next step is to configure Git. To do this, run the following commands from the command line:

git config –global user.name “YOUR_NAME”
git config –global user.email “YOUR_EMAIL”

3. Now we are ready to create a Git repository. To do that, create a new directory where you want to store your project files. For this blog, I have created a new folder called “hellogit” and moved to the folder in the terminal.

To create a new repository, simply run the following command in the project folder:

4. Now we are ready to add files to our repository. Assume that we have two files in our project test.html and test2.html. Move the files into the hellogit project folder.

Now run the git status command to know the latest status of our repository:

Git comes back saying that we have two untracked files. Git does not automatically track the files in our repository. Instead we need to explicitly add them.

5. To add files to Git, simply run the following command:

If you are new to Git, you might be wondering about the lack of feedback from Git about the add command. Just remember that upon a successful command execution, Git typically does not give you any feedback.

Let’s run the status command to see what happened:

From the above image, you can see that Git added our two files. It also mentions that we have a OS specific file DS_Store that needs to be tracked. We will address that in a minute.

6. When we are done making changes to our project files, we can check them in. To do that, simply run the following command:

In the above command, I have given a commit message “Initial Commit”.

7. Often we will end up with project and OS specific files (DS_Store) in our project folder that we don’t want to check in to Git. We can tell Git to ignore certain files and never track them. To do that, we simply create a .gitignore file that has the name(s) of the file that needs to be ignored.

Now, when the .gitignore file is in place, run the status command and you will see that the .DS_Store file is no longer tracked.

Preparing For Github

Before you can start using Github remote repository, you need to setup SSH keys. These keys are needed to establish secure connection between your computer and Github. To do that follow these steps:
1. Run the following command:

The No such file or directory indicates that you don’t have any SSH keys. Sometimes, the folder might exist but it might not have the id_rsa* SSH key files.

2. The next step is to create a new SSH key. Run the following command:

Hit enter to accept the default location. You will be asked to enter a passphrase. Enter a pass phrase and make a note of it as we will need it again.

Connecting To Github

1. Before we can push our code to a github repository, we need to create an account. Go to http://github.com and create a new account.

2. Once you have created and logged into your account, you need to give github your SSH key. In order to do that, go to your account settings page and click the SSH Keys Navigation Item:

3. Copy the SSH key you created above. To do that, simply go to the .ssh folder and type the following command:

4. Click the Add SSH Key button and enter the key as well as a title.

5. Go back to the terminal and try to connect to github using this command:

When you accept Yes, you will be asked to enter the passphrase:

Check the “Remember Password in keychain” and hit Ok.

6. Now, we are ready to start pushing code to Github. Before we do that we need to create a remote repository on Github. To do that, click the New Repository button:

Enter the following information for the new repository:

Make sure you leave all the fields in their default state.

7. Once the repository has been created on Github, move to your terminal and cd.. into the hellogit project. Then run the following two commands (replace bava with your username):

Now, go back to your Github repository https://github.com/YOUR_USER_NAME/hellogit and you will see that the files have been pushed.

Categories: Git, Solutions Log Tags: ,

SiteMesh And Script Tag

July 29th, 2010 No comments

In a Sitemesh application I recently had to read code inside <script> tags of the decorated pages and use it in the decorator page. After little research, I found this solution. Based on this, I extended the HTMLPageParser and created a ScriptExtractionRule. The ScriptExtractionRule extends the BlockExtractingRule and retrives the content inside script tag.

However with Sitemesh 2.4.1, this solution did not work for the script tag. When I replaced script with any other HTML tag such as form, I was able to read the content inside that tag. Eventually I ended up putting the JavaScript inside a content tag. Here is a portion of the decorated page.

<content tag=”script”>
function somejsfunction() {
}
</content>

Now in the decorator page, I used the tag to read the JavaScript. Hopefully this helps others struggling with similar issue.

Categories: SiteMesh, Solutions Log Tags: