Saturday, January 1, 2011

Upcoming Tutorials

Happy New Year! Welcome to the year 2011.

As of now I'm writing the following tutorials:

- Apache DS step-by-step guide
- Spring Security - LDAP integration
- Spring WS - WSS4J
- Spring Security - Multiple Entry Points

Stay tune! Share the fun :)
StumpleUpon DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google I'm reading: Upcoming Tutorials ~ Twitter FaceBook

Subscribe by reader Subscribe by email Share

Friday, December 31, 2010

Spring MVC 3 - Tiles 2 Integration Tutorial

In this tutorial we will build a simple Spring MVC 3 application that utilizes templates using the Apache Tile 2 framework. We will create a template version of our pages, and compare it with non-template versions of the same pages. We will split the content, style, and template of these pages logically.

What is Apache Tiles 2?
Apache Tiles is a templating framework built to simplify the development of web application user interfaces.

Tiles allows authors to define page fragments which can be assembled into a complete page at runtime. These fragments, or tiles, can be used as simple includes in order to reduce the duplication of common page elements or embedded within other tiles to develop a series of reusable templates. These templates streamline the development of a consistent look and feel across an entire application.

Source: Apache Tiles 2

Our MVC application is about pet information. The main page describes pets in general. The other two pages are speficic for dogs and cats . We will develop our application using standard JSP. Then later, we'll create a Tiles version.

Let's start with the Pets page.

pets.jsp

There are four major div elements here. Each one has been assigned an id so that we can style them using CSS.

Here's the actual screenshot of the Pets page:

Here's the Dogs page.

dogs.jsp

There are five major div elements here. Each one has been assigned an id so that we can style them using CSS.

Here's the actual screenshot of the Dogs page

Here's the Cats page.

cats.jsp

Here's the actual screenshot of the Cats page

We also have the same five major div elements here.

In order for these JSP pages to be served in Spring MVC, we need to declare the corresponding controller.

NoTilesController

This controller has three mappings:
/notiles/pets - for displaying the pets page
/notiles/dogs - for displaying the dogs page
/notiles/cats - for displaying the cats page
To load the pets page, enter the following url:
http://localhost:8080/spring-tiles/krams/notiles/pets
To load the dogs page, enter the following url:
http://localhost:8080/spring-tiles/krams/notiles/dogs
To load the cats page, enter the following url:
http://localhost:8080/spring-tiles/krams/notiles/cats
That's it. We've developed a simple Spring MVC 3 application using standard JSPs.

However, we have a problem

We've declared three JSP pages. Imagine if we have 100 JSP pages to managed with. We need to modify the title and the footer. So we open all 100 JSP pages, edit them one by one. To make it faster, we copy and paste the same code. But we made a typo. So we edit again those 100 pages. And the cycle goes on. What if we have 500 pages? 1000? How do we make our lives less difficult?

Enter Apache Tiles 2

Let's refactor our JSPs. Remember in each of these pages there are major div elements. We'll use those as markers for our templates.

The Pets page uses the following structure:

Our first template is based on this structure.

main.jsp

Each div contains a tiles:insertAttribute element. These are placeholders for the actual content.

Our second template will be based on the cats.jsp and dogs.jsp. They share the same structure so that means they will share the same template.

details.jsp

So far we have created 5 JSPs:
cats.jsp - a standard JSP
dogs.jsp - a standard JSP 
pets.jsp - a standard JSP 

detail.jsp - a Tiles JSP 
main.jsp - a Tiles JSP 
To use these templates we need to activate Apache Tiles by declaring the required XML configurations. To do that we need to declare the required Spring configurations as well.

We'll start with the web.xml.

web.xml

Take note of the URL pattern. When accessing any pages in our MVC application, the host name must be appended with
/krams
In the web.xml we declared a servlet-name spring. By convention, we must declare a spring-servlet.xml as well.

spring-servlet.xml

This XML config declares a view resolver. All references to a JSP name in the controllers will map to a corresponding JSP in the /WEB-INF/jsp location.

By convention, we must declare an applicationContext.xml

applicationContext.xml

This XML config declares three beans to activate the Spring 3 MVC programming model. W've also imported a resource tiles-context.xml. This contains the Tiles configuration.

tiles-context.xml

This configuration declares required beans to activate Tiles. The TilesConfigurer relies on an external definitions file tiles-definitions.xml for the actual declaration of the templates.

tiles-definitions.xml

We've declared two templates: template-main and template-detail.

These attributes must match the attributes you declared in template: main.jsp

We've declared three concrete pages: pet-tiles, dog-tiles, cat-tiles

Each concrete page extends a template name. For example, cat-tiles extends from template-detail. In Java this is comparable to inheritance.

Do you understand now how Tiles can help us reduce repetitive code and lessen errors? By reusing the same JSP and template, we improve our development time. Our JSPs became manageable. If you want to switch content, you just do it in the tiles-definitions.xml. For example, if you need to update the footer.jsp, you just open the file. Edit then save. You don't need to edit 1000 JSP pages anymore.

Of course, if you're just dealing with three pages. The initial configuration might be too much. But in real-life applications, it's a time saver because you're dealing with lots of JSPs.

Because we're still dealing with a MVC application, we need to declare another controller to handle these Tiles pages.

TilesController

This controller has three mappings:
/tiles/pets - for displaying the pets page
/tiles/dogs - for displaying the dogs page
/tiles/cats - for displaying the cats page
To load the pets page, enter the following url:
http://localhost:8080/spring-tiles/krams/tiles/pets
To load the dogs page, enter the following url:
http://localhost:8080/spring-tiles/krams/tiles/dogs
To load the cats page, enter the following url:
http://localhost:8080/spring-tiles/krams/tiles/cats

Let's compare side by side our JSP pages with using the standard JSPs and the ones with Tiles support.

Pets Page (before and after)

Dogs Page (before and after)

Cats Page (before and after)

That's it. We've managed to refactor our code and use the Tiles framework. We've also leveraged on Spring programming model to develop our MVC application.

The best way to learn further is to try the actual application.

Download the project
You can access the project site at Google's Project Hosting at http://code.google.com/p/spring-mvc-tiles/

You can download the project as a Maven build. Look for the spring-tiles.zip in the Download sections.

You can run the project directly using an embedded server via Maven.
For Tomcat: mvn tomcat:run
For Jetty: mvn jetty:run
StumpleUpon DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google I'm reading: Spring MVC 3 - Tiles 2 Integration Tutorial ~ Twitter FaceBook

Subscribe by reader Subscribe by email Share

Spring Security - MVC: Implementing a Single Entry Filter Tutorial

In this tutorial we will implement a custom Spring Security filter that allows a URL to be accessed just once. We will position the filter after the CONCURRENT_SESSION_FILTER. We will take advantage of the SessionRegistry to query the current session. If you're not familiar with setting-up the SessionRegistry and Concurrent Session Management, please read first the Spring Security - MVC: Querying the SessionRegistry tutorial.

The requirements for our custom filter are the following:
  • You can only have one instance of a page
  • If you create a new tab and enter the same page, you will not be able to access the page again and you will be redirected to a custom page
  • If you create a new browser, same result
  • If you create close and open the same browser, same result
  • If you refresh the same tab, same result
  • You can only gain access if you manually log-out
  • You can only gain access if you clear your browser's cache
  • You can only gain access if your session has expired
So how do we do that? First, we evaluate at what position in the FilterProxyChain should we place this filter. We need the SessionRegistry and we need the HttpServletRequest. Somewhere around the CONCURRENT_SESSION_FILTER looks promising.

If you need to learn more about the FilterChainProxy and ordering of the aliases, please check the Spring Security Reference Table 2.1. Standard Filter Aliases and Ordering

The format for adding the filter is similar to the following:


Before we start adding real code, let's declare a pseudocode first:
if user has logged-in for the first time
   flag the session that the user has logged-in
if the user tries to log-in again
   check if there's a protected URL
       if yes, redirect user to a custom page
       if no, then proceed with the remaining filters
And here's the actual implementation for this filter.

SingleEntryFilter

This filter extends OncePerRequestFilter and overrides the doFilterInternal() method

What is OncePerRequestFilter?
Filter base class that guarantees to be just executed once per request, on any servlet container. It provides a doFilterInternal(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, javax.servlet.FilterChain) method with HttpServletRequest and HttpServletResponse arguments.

The getAlreadyFilteredAttributeName() method determines how to identify that a request is already filtered. The default implementation is based on the configured name of the concrete filter instance.

Source: Spring Reference 3 for OncePerRequestFilter
How did we came up with this implementation? I'm sure it didn't just came out from thin air. Actually, I had to study how the CONCURRENT_SESSION_FILTER alias is implemented. It's filter class is based on ConcurrentSessionFilter.

What is ConcurrentSessionFilter?
Filter required by concurrent session handling package.

This filter performs two functions. First, it calls SessionRegistry.refreshLastRequest(String) for each request so that registered sessions always have a correct "last update" date/time. Second, it retrieves a SessionInformation from the SessionRegistry for each request and checks if the session has been marked as expired. If it has been marked as expired, the configured logout handlers will be called (as happens with LogoutFilter), typically to invalidate the session. A redirect to the expiredURL specified will be performed, and the session invalidation will cause an HttpSessionDestroyedEvent to be published via the HttpSessionEventPublisher registered in web.xml.

Source: Spring Security 3 Reference for ConcurrentSessionFilter
Let's examine the doFilter() method of this class.

ConcurrentSessionFilter

This ConcurrentSessionFilter does the following steps:
1. Retrieve the current session
2. Check if session is not null
3. Check if the SessionInformation is not null
4. Check if the session has expired. If expired, logout and redirect
5. If not expired, continue with remaining filters.

Let's compare this with our custom filter SingleEntryFilter.

Inside the doFilterInternal() method, we do the following:
1. Retrieve the current session and verify if it's not null

2. Retrieve the SessionInformation and verify if it's not null

3. Retrieve the session attribute hasLoggedIn and check if it's null or not

If hasLoggedIn is not null, this means the user has logged already.

4. Next, we loop the guardURI list and check if there's a protected URL. If there's one, we redirect to the redirectURI

5. If this is the user's first time to access the site (i.e new session), set the hasLoggedIn attribute

6. Finally, continue with the remaining filters

Examine how this code resembles the ConcurrentSessionFilter

Now, let's update the the Spring Security XML configuration.

spring-security.xml

The changes we did in this file is we added the following custom filter:

We also declared the singleEntryFilter bean.

Notice the guardURI is a list. That means we can protect multiple URIs. Cool :)

We then need to update our login controller so that we can see the invalid login alert.

LoginLogoutController

To access the site, please login first by entering the following URL:
http://localhost:8080/spring-security-single-login-filter/krams/auth/login
Then access the following URL:
http://localhost:8080/spring-security-single-login-filter/krams/main/common
You can only access the URL once! Here's what you'll get if you try again:

That's it. We've just finished implementing our custom filter based on the requirements we laid earlier. They key action here is we studied the existing filters to see how Spring Security does things. I believe this is a good way to enhance one's knowledge of this framework.

Please read the tutorial Spring Security 3 - MVC: Querying the SessionRegistry for a complete step-by-step guide for the other parts of this application.

The best way to learn further is to try the actual application.

Download the project
You can access the project site at Google's Project Hosting at http://code.google.com/p/spring3-security-mvc-integration-tutorial/

You can download the project as a Maven build. Look for the spring-security-single-login-filter.zip in the Download sections.

You can run the project directly using an embedded server via Maven.
For Tomcat: mvn tomcat:run
For Jetty: mvn jetty:run
StumpleUpon DiggIt! Del.icio.us Blinklist Yahoo Furl Technorati Simpy Spurl Reddit Google I'm reading: Spring Security - MVC: Implementing a Single Entry Filter Tutorial ~ Twitter FaceBook

Subscribe by reader Subscribe by email Share