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.