Java Web Application Development With Click Framework/Best Practices

This section discusses Best Practices for designing and building Click application. The following topics are covered:


 * Use JEE role-based security
 * Project package structures and page classes
 * Use Convention over Configuration
 * Use Page classes to forward and redirect
 * Standardize your web application
 * Centralize your page navigation
 * Use Log4j in a base page
 * Use custom error pages

Security
For application security it is highly recommended that you use the declarative JEE Servlet path role based security model. While Click pages provide an onSecurityCheck method for rolling your own programatic security model, the declarative JEE model provides numerous advantages.

These advantages include:


 * Its an industry standard pattern making development and maintenance easier.
 * Application servers generally provide numerous ways of integration with an organisations security infrastructure, including LDAP directories and relational databases.
 * Servlet security model support users bookmarking pages. When users go to access these pages later, the container will automatically authenticate them before allowing them to access the resource.
 * Using this security model you can keep your Page code free of security concerns. This makes you code more reusable, or at least easier to write.

If your application has very fine grained or complex security requirements you may need to combine both the JEE declarative security model and a programmatic security model to meet your needs. In these cases its recommended you use declarative security for course grained access and programmatic security for finner grained access control.

Declarative Security
The declarative JEE Servlet security model requires users to be authenticated and in the right roles before they can access secure resources. Relative to many of the JEE specifications the Servlet security model is surprisingly simple.

For example to secure admin pages, you add a security constraint in your web.xml file. This requires users to be in the admin role before they can access to any resources under the admin directory:

The application user roles are defined in the web.xml file as security-role elements:

The Servlet security model supports three different authentication method:


 * BASIC - only recommended for internal applications where security is not important. This is the easiest authentication method, which simply displays a dialog box to users requiring them to authenticate before accessing secure resources. The BASIC method is relatively unsecure as the username and password are posted to the server as a Base64 encoded string.
 * DIGEST - recommended for internal applications with a moderate level of security. As with BASIC authentication, this method simply displays a dialog box to users requiring them to authenticate before accessing secure resources. Not all application servers support DIGEST authentication, with only more recent versions of Apache Tomcat supporting this method.
 * FORM - recommended applications for where you need a customised login page. For applications requiring a high level of security it is recommended that you use the FORM method over HTTPS.

The authentication method is specified in the &lt;login-method&gt; element. For example to use the BASIC authentication method you would specify:

To use the FORM method you also need to specify the path to the login page and the login error page:

In your Click <tt>login.htm</tt> page you need to include a special <tt>j_security_check</tt> form which includes the input fields <tt>j_username</tt> and <tt>j_password</tt>. For example:

<script type="text/javascript"> document.form.j_username.focus;

When using FORM based authentication do NOT put application logic in a Click Login Page class, as the role of this page is to simply render the login form. If you attempt to put navigation logic in your Login Page class, the JEE Container may simply ignore it or throw errors.

Putting this all together below is a <tt>web.xml</tt> snippet which features security constraints for pages under the admin path and the user path. This configuration uses the FORM method for authentication, and will also redirect unauthorized (403) requests to the <tt>/not-authorized.htm</tt> page.

Resources
For more information on using security see the resources below:


 * Form Based Authentication by Louis E. Mauget
 * Servlet Specification by Sun Microsystems
 * Basic authentication scheme
 * Digest authentication scheme
 * Https URI scheme

Packages and Classes
An excellent way to design your project package structure is the classify packages initially by technology. So in a Click application all of our pages would be contained under a <tt>page</tt> package. This also works very well with the Page automapping feature.

All the projects domain entity classes would be contained under a <tt>entity</tt> package, and service classes would be contained under a <tt>service</tt> directory. Note alternative names for the <tt>entity</tt> package include domain or model. We also typically have a <tt>util</tt> package for any stray classes which don't quite fit into the other packages.

In Java package names are singular by convention, so we have a util package rather than an utils package.

An example project structure for a MyCorp web application is illustrated below:



In this example application we use declarative role and path based security. All the pages in the <tt>admin</tt> package and directory require the <tt>"admin"</tt> role to be access, while all the pages in the <tt>user</tt> package and directory require the <tt>"user"</tt> role to be accessed.

Page Classes
A best practice when developing application Page classes is to place common methods in a base page class. This is typically used for providing access methods to application services and logger objects.

For example the BasePage below provides access to Spring configured service objects and a Log4J logger object:

Applications typically use a border template and have a <tt>BorderPage</tt> which extends <tt>BasePage</tt> and defines the template. For example:

Most application pages subclass <tt>BorderPage</tt>, except AJAX pages which have no need for a HTML border template and typically extend <tt>BasePage</tt>. The <tt>BorderPage</tt> class should not include common logic, other than that required for rendering the border template. Common page logic should be defined in the <tt>BasePage</tt> class.

To prevent these base Page classes being auto mapped, and becoming directly accessible web pages, ensure that there are no page templates which could match their class name. For example the <tt>BorderPage</tt> class above will not be auto mapped to border-template.htm.

Page Auto Mapping
You should use the Click page automapping configuration feature.

Automapping will save you from having to manually configure URL path to Page class mappings in your <tt>click.xml</tt> file. If you follow this convention it is very easy to maintain and refactor applications.

You can also quickly determine what the corresponding Page class is for a page HTML template and visa versa, and if you use the ClickIDE Eclipse plugin you can switch between a page's class and template by pressing Ctrl Alt S.

An example <tt>click.xml</tt> automapping configuration is provided below (automapping is enabled by default):

To see how the page templates are mapped to Page classes set the application mode to <tt>debug</tt> and at startup the mappings will be listed out. An example Click startup listing is provided below:

[Click] [debug] automapped pages: [Click] [debug] /category-tree.htm -&gt; com.mycorp.dashboard.page.CategoryTree [Click] [debug] /process-list.htm -&gt; com.mycorp.dashboard.page.ProcessList [Click] [debug] /user-list.htm -&gt; com.mycorp.dashboard.page.UserList

Navigation
When navigating between Pages using forwards and redirects, you should refer to the target page using the Page class rather than using path. This provides you compile time checking and will save you from having to update path strings in Java code if you move pages about.

To forward to another page using the Page class:

To redirect to another page using the Page class you can obtain the pages path from the <tt>Context</tt>. In the example below we are passing through the customer id as a request parameter to the target page.

A quick way of redirecting to another page is to simply refer to the target class. The example below logs a user out, by invalidating their session, and then redirects them to the applications home page.

Templating
Use Page templating - it is highly recommended. Page templates provide numerous advantages including:


 * greatly reduce the amount of HTML you need to maintain
 * ensure you have a common look and feel across your application
 * make global application changes very easy

Menus
For many applications using the Menu control to centralize application navigation is very useful. Menus are defined in a <tt>WEB-INF/menu.xml</tt> file which changes very easy.

An menu is typically defined in the a page border template so they are available through out the application. The Menu control does not support HTML rendering, so you need to define a Velocity macro to programattically render the menu. You would call the macro in your border template with code like this:


 * #writeMenu($rootMenu)

An advantage of using a macro to render your menu is that you can reuse the code across different applications, and to modify an applications menu you simply need to edit the <tt>WEB-INF/menu.xml</tt> file. A good place to define your macros is in the webroot <tt>/macro.vm</tt> file as it is automatically included by Click.

Using macros you can create dynamic menu behaviour such as only rendering menu items a user is authorized to access with <tt>isUserInRoles</tt>.

You can also use JavaScript to add dynamic behaviour such as drop down menus..

Logging
For page logging you should use Log4j library. An alternative library is the Commons Logging. If you are using Commons Logging please be aware that there have been class loader issues with this library on some application servers. If you are using Commons Logging please make sure you have the latest version.

The best place to define your logger is in a common base page, for example:

Using this pattern all your application bases should extend <tt>BasePage</tt> so they can use the <tt>getLogger</tt> method.

If you have some very heavy debug statement you should possibly use an <tt>isDebugEnabled</tt> switch so it is not invoked if debug is not required.

Please note the Click logging facility is not designed for application use, and is for Click internal use only. When Click is running in <tt>production</tt> mode it will not produce any logging output.

Error Handling
In Click unhandled errors are directed to the ErrorPage for display. If applications require additional error handling they can create and register a custom error page in <tt>WEB-INF/click.xml</tt>. For example:

Generally application handle transactional errors using service layer code or via a servlet Filter and would not need to include error handling logic in an error page.

Potential uses for a custom error page include custom logging.

For example if an application requires unhandled errors to be logged to an application log (rather than System.out) then a custom ErrorPage could be configured. An example <tt>ErrorPage</tt> error logging page is provided below: