Win a copy of Re-engineering Legacy Software this week in the Refactoring forum
or Docker in Action in the Agile forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

enforcing navigation - How did YOU do it?

Jason Berk
Ranch Hand
Posts: 41
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
hello all,

Looking for how others have enforced site navigation. I have a relatively small web app with the following "views" (jsp):

1) identifyUser (has radio to select staff or customer)
2) verifyStaff
3) verifyCustomer
4) verifyCustomerExtended
5) confirmRequest
6) requestSuccessful

A user MUST follow one of the following paths of navigation:
1 - 2 - 5 - 6 OR 1 - 3 - 4 - 5 - 6

each page expects you to have completed the previous page.

I'm trying to set up our environment here at work to be reusable and that's
where things get sticky. Let's say I have three WARs (apps) all using struts. Each app specifies it's request processor as:

All of which extend... (which extends TilesRequestProcessor) a fourth project.

My SharedTilesRequestProcessor looks like so:

//this is so children can use the preprocess method
protected abstract void getPreprocessHook(HttpServletRequest request, HttpServletResponse response)throws ServletException;

//this is so individual apps can provide navigation rules to the
//application independant check navigation method declared here
protected abstract Object getNavRules()throws Exception;

protected boolean processPreprocess
(HttpServletRequest request, HttpServletResponse response) {
boolean continueProcessing = true;
String appName = "NAME NOT SET";
HttpSession session = request.getSession();
MessageResources resources = (MessageResources)
appName = resources.getMessage("APPLICATION.VIEWABLE.NAME");
session.setAttribute("APPLICATION_NAME", appName);
//add checkNavigation(request, response, getNavRules())
getPreprocessHook(request, response);
} catch (Exception e) {
continueProcessing = false;
logger.error(appName + ": Exception Caught during Preprocessing");
logger.error(appName + ": " + e.getMessage(), e);
try {
request.getSession().setAttribute("errorMessage", null);
} catch (Exception ee) {
logger.error(appName + ": forwarding error - "
+ ee.getMessage(), ee);
return continueProcessing;

I'd like to add a "checkNavigation" method (commented in code) to this class (along with any other needed helper methods).

Is this even possible?

Seems to me the work of enforcing navigation can be abstracted to one location. Given requested URI "x" and application state "y", you either succeed or fail (maybe even throw a custom "IllegalNavigationException"). Seems silly that each WAR would have to reinvent the wheel regarding navigation enforcement. Each app should only have to provide the structures (be it hashmaps, xml, etc) which define what state the app must be in for a received request to be worthy of (further) processing.

this idea is a modification of the recipe I read in the "Struts Recipes" book by Franciscus & Gurovich. I like their solution but I would like to abstract it "up a level" so any WAR which provides a "state/request ruleset" can benifet from it

Have I lost my mind here? How are others accomplishing this? Is there YAF (Yet another framework) I should be using.

I've been reading about Tapestry, Velocity, Spring (with and without struts), and wondered if they might be my answer.

I'm beginning to wonder if maybe I'm missing one of the points of struts....seems the framework would rather you rebuild the wheel each application, but will help you rebuild the wheel identically to the way you built it last time....does that even make sense?

Thanks for any input,


[ June 27, 2006: Message edited by: Jason Berk ]

[ June 27, 2006: Message edited by: Jason Berk ]
[ June 27, 2006: Message edited by: Jason Berk ]
Merrill Higginson
Ranch Hand
Posts: 4864
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you're askiing how I handle navigation, here's how:

1-The navigation rules for the applications that I write have so far not been complicated enough to require a "navigation rules engine" like you're creating. In my opinion, such an engine would only be needed if the navigation rules are exceptionally complicated, or if they are expected to change frequently.

2-In most cases for my applications there is only one navigation rule for each page, and that is "User must be logged in before accessing this page". I handle that rule by creating a base Action class from which all other action classes are extended. The base action has code to check that the user is logged on before performing the action.

3-In cases where user must perform Action A before performing Action B, the first line of defense is the User interface. I simply don't provide a link or button to perforom action B from anywhere except in Action A. The second line of defense (needed only in case the user bookmarks a page) is in the action class itself. In the Action class for Action B, I detect that Action A has not been performed, usually by the absense of some required object in the session, and display an error page if it's not there.

Just as it's possible for a boss to do too much micro-managing of employees, I think it's also possible for an architect to create frameworks that do too much mirco-managing of the applications the developers will write. Some things are just better left to the developer's discretion or handled with a general guideline rather than a tight-fitting framework.
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic