Successful Software Development

February 27, 2010

Customizing the user experience using Seam, JSF and EL

Filed under: Java, Seam — Martin van Vliet @ 12:57 am

A web application may be used by many different types of users of varying skill levels. While it is easy to build the site with a one-size-fits-all user experience, many companies these days want to provide a customized user experience, tailored to the user’s needs. Here are some possibilities for this using the Seam framework.

The simplest way to customize the user experience is to put conditional behaviour in the web pages. This can be done using tags and EL. Seam helps in this respect because it makes all sorts of objects, including the current logged in use, available via EL. An example could be:

<c:if test="#{loggedInUser.userType eq 'C1'}" >
  <h1>Welcome, C1 user!</h1>
</c:if>

Of course, this does mean that one page that has a lot of user-dependent variations will become riddled with these statements. If this is the case, a page-based approach is better. Using EL in Seam’s navigation configuration can do this. For example, the following fragment shows how to conditionally render a different version of a page:

	<page view-id="*">
		<navigation from-action="#{searchAction.findCompanies(companySearchCriteria)}">
			<rule if="#{loggedInUser.userType eq 'C1'}">
				<redirect view-id="/pages/search/SearchResultsC1.xhtml"/>
			</rule>
			<redirect view-id="/pages/search/searchResults.xhtml"/>
		</navigation>
	</page>

Finally, different users may require different implementations of backend services. For example, a particular class of user may only be allowed to see a subset of search results as compared to another class of user. One way to do this is to use EL to drive dependency injection. Given the dependency below:

	@In(value="#{serviceInjector.injectService('companyService')}")
	private CompanyService companyService;

a ServiceInjector class containing the following functionality:

@Name("serviceInjector")
public class ServiceInjector {
    @In
    private User loggedInUser;
    @In
    private WebAppContextService webAppContextService;
    public Object injectService(String param) {
    	Object result = webAppContextService.lookupBeanOrComponent(param + loggedInUser.getUserType());
    	if (result == null) {
    		result = webAppContextService.lookupBeanOrComponent(param);
    	}
    	return result;
    }
}

would attempt to inject a user-class specific service instance, falling back to the regular instance if one didn’t exist.

The attribute to base this choice on is not restricted to a simple enumeration. Since these are Java methods being invoked, all sorts of logic is possible, such as giving a user a preview of a particular piece of functionality but requiring him to subscribe after 10 uses or a temporary promotional campaign.

Advertisement

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Theme: Shocking Blue Green. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.