Spring & JSF integration: Dynamic Navigation

Often your JSF application will need to move beyond basic static navigation and start to make dynamic navigation decisions. For example, you may want to redirect users based on their age. Most JSF tutorials recommend that dynamic navigation is implemented by binding the action attribute of a command to a backing bean:

<h:commandButton action="#{bean.actionBasedOnAge}"/>
public String actionBasedOnAge() {
  if(age &lt; 12) {
    return "fetchadult";
  } else {
    return "ok"
  }
}

The example above shows how anyone under twelve is directed to 'fetchadult' instead of the usual 'ok'. Both the 'fetchadult' and 'ok' outcomes will need to have navigation rules defined in the faces-config.xml so that JSF knows what actual page to display.

When working with Spring MVC it is often more natural to have navigation logic contained in the @Controller bean. To help with this, implicit 'controller' and 'handler' variables are available when rendering JSF from MVC. The 'controller' variable provides access to the controller bean that was mapped to the original request, and the 'handler' variable to the underling MVC handler. In Spring 3.0 'controller' and 'handler' are generally the same object. In Spring 3.1 however, the underlying MVC architecture is changing and 'handler' will generally be a org.springframework.web.method.HandlerMethod instance.

Here is a submit button that references the someNavigation() method of the the @Controller:

<h:commandButton action="#{controller.someNavigation"/>

Whilst accessing the controller bean is useful, it is not the ideal solution. I prefer to use logical names in my JSF pages and map those the Java methods. I also want an easy way to get back to data from the underlying model.

The @NavigationMapping annotation provides another, more flexible approach to handling navigation. It works in a very similar way to @RequestMappings. The annotation can be placed on any public method in your @Controller to map navigation outcomes to destinations.

<h:commandButton action="submit"/>
@NavigationMapping
public String onSubmit() {
  return "redirect:http://www.springsource.org";
}

If you need access to a backing bean the standard Spring @Value annotation can be used. Any EL expression that the page can resolve can also be used on a navigation method parameter.

@NavigationMapping
public String onSubmit(@Value("#{person.age}") int age) {
...
}

Accessing model elements is even easier. As long as you only have a single object of the type you want to access in your model, and it is not a simple type (int, String, etc), you don’t need any annotations:

@NavigationMapping
public String onSubmit(Person p) {
...
}

Other argument types can also be used (see the JavaDoc for a complete list). For example, here is a navigation mapping that handles 'submit', 'cancel' and 'save' outcomes. The injected arguments tell us the which of the three outcomes was clicked and provides access to the source UIComponent.

@NavigationMapping('submit','cancel','save')
public String handleNavigation(String outcome, UIComponent source) {
...
}

Return types are also equally flexible. You can return view names as Strings, you can also use the same "@hotelsController.show" notation that I have previously blogged about. You can also return View objects directly or you can use NavigationOutcome if you want to include implicit model items.

Finally, if you just want to render an immediate response you can use the @ResponseBody annotation or return a HttpEntity. This works in exactly the same way as Spring.

Reference: Integrating Spring & JavaServer Faces : Dynamic Navigation from our JCG partner Phillip Webb at the Phil Webb’s Blog blog.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

Leave a Reply


+ 2 = ten



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close