The Way from JSF to MVC 1.0….

In this tutorial I will try to figure out how the new Web Framework MVC 1.0 works and what this means to the established JSF developer. So if you are familiar with JSF this may help you to discover a new framework for Web applications.

Goodbye POST Back ….

I am personal developing JSF web applications since the early beginning in 2004. JSF has evolved and I learned to work with it. But over the years I loved it and I hated it. The JSF Framework is a so called ‘event driven’ framework. The JSF engine reacts on action events (typically happening when the user click on links or buttons in a page) and returns a HTML result. For example if we have a starting page “/welcome.xhtml”  we can open the application be a URL like:

http://localhost:8080/my-app/welcome.jsf

This page, for example may provide some input fields and one or many action links. In JSF an action is typically combined with a action result and optional an actionListener to trigger some business logic. In JSF such an element can look like this:

<h:commandButton value="Go to Shop"
    actionListener=#{myController.startShopping()}
    action="/my_shop.jsf" />

As a newcomer in JSF you would expect that after clicking the command button in this case the Browser URL switches from “/welcome.jsf” to the new URL defined by the action event – “/my_shop.jsf“. But this is not the case and it can be a confusing behavior in JSF. The Browser URL will stay on “/welcome.jsf” even when the user sees the content of the new page “/my_shop.jsf“. The reason for this behavior is that the JSF action event itself results in a HTML POST method. This means the browser sends the form data to the backend in a POST request based on the origin URL, which is still “/welcome.jsf“. The JSF Framework evaluates and validates the data, runs optional business logic and renders the outcome form the action result page “my_shop.jsf“. The user will see the new page output of “/my_shop.jsf”, but the Browser URL will not change and is still pointing to “welcome.jsf“. But on the next JSF event triggered by the new page, the browser URL will change to “my_shop.jsf“, independent which URL result was triggered by the 2nd event. This is called a POST Back. The Browser URL in this case is always one page behind. Over the years this Post Back  mechanism has lead to endless discussions and solutions how to mange URL Bookmarks or the Browser History Back Button, triggered by the user. Of course, today there are some solutions like the URL extension “?redirect=true” or the <h:link> element. But my personal view is, that it is a pointless fight against a concept which is not clear to the user.

…Welcome Actions!

MVC 1.0 is an action based web framework. And this is a complete reversal of the event based JSF framework. For established JSF developers this means you need to learn a new concept and forget all you have done over the years in JSF. The good news is, the action-based concept is simple and clear and so it’s much easier to learn.

One reason for this is that MVC 1.0 is layered on top of JAX-RS and integrates with existing EE technologies like Facelets, CDI or Bean Validation. This means, if you have already experience with REST you can understand MVC 1.0 quick and easily.

The Navigation Concept

To understand the concept of MVC 1.0 you can first think in the way of a Rest API. If you write a Rest API method in JAX-RS your code may looks something like this:

@Path("/myservice")
@Produces({MediaType.APPLICATION_JSON})
public class MyRestService {
   @GET
   @Path("/shopping-cart")
   public String showCart() {
      String outcome="";
      // some business logic to compute outcome
      ... 
      return outcome;
   }
}

The URL “/myservice/shopping-cart” will trigger the business method. The method computes the outcome which is the result of the GET request. For a Rest API this is fine because we typically compute the result in a technical representation like XML or JSON. But for a Web Application JAX-RS is of course no solution. You may not want to render a complete HTML page (like is was usual in the year 1997 with the first Servlet API).

Now here comes MVC 1.0 with a simple solution. As an outcome of your method you simply point to a HTML Page (or a JSP or JSF page, or something else you are familiar with) and MVC 1.0 will render the result together with the URL defined by your JAX-RS method:

@Controller // make this bean an MVC 1.0 controller
@Path("myapp") // the URL pattern
@Named
public class ShoppingController {
    String userID;
    // getter/setters
    .... 
    
    // action URL
    @GET
    @Path("/shopping-cart")
    public StringshowCart() {
        // some business logic to compute outcome 
        ... 
        return "shopping-cart.xhtml";
    }
}

In this example, the user can call the URL “/myapp/shopping-cart“,  the MVC Controller performs some business logic and than renders the output of the page “shopping-cart.xhtml” which is returned as a HTML result.

So when the user calls in his Browser the URL “/myapp/shopping-cart” he will see the content of the “shopping-cart.xhtml” page. The interesting part for JSF developers here is, that you can reuse all your knowledge in using technologies like Facelets, Backing Beans or Bean Validation. So for example with Facelets, which is a great template framework for web pages, you can easily build your application pages. And of course you have a backing bean out of the box, providing you with a data model.

Let’s take a look at the following example of a facelets  page:

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
 xmlns:ui="http://java.sun.com/jsf/facelets"
 template="/layout/template.xhtml">
  <ui:define name="content">
    <h1>Welcome #{shoppingController.userID}</h1>
    <a href="myapp/payment">go to payment</a>
   </ui:define>
</ui:composition>

This page, which can the result of a MVC 1.0 action controller, contains facelets fragments, the CDI bean ‘shoppingController’ and a navigation link. The xhtml page is placed into the folder “/WEB-INF/views/” of your web application. This is the place where the MVC 1.0 looks for result pages per default. But why are these pages hidden in the /WEB-INF/views/ folder? The reason is simple – you do not want our pages become accessible directly from a web browser by the user. In MVC 1.0 you only work with URL patterns defined by JAX-RS.

You can see this fact by the embedded navigation link in the example. The link is a simple HTML anchor tag pointing to a defined JAX-RS path. This link is of course bookmark-able and navigating between different URLs can also be reversed by using the Browser Back button!

Using Facelets

As you can see in my example, I am using jsf/facelets technology. JSF Faclets is well supported also from MVC 1.0 and can be used to use templates and building blocks to construct a page.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
 xmlns:h="http://java.sun.com/jsf/html"
 xmlns:f="http://java.sun.com/jsf/core"
 xmlns:ui="http://java.sun.com/jsf/facelets">

<h:head>
 <title>#{app.application_title}</title>
 <ui:insert name="header">
 <!-- default -->
 </ui:insert>
</h:head>
<h:body>
 <f:view>
 <!-- content -->
 <div id="container">
 <ui:insert name="content">
 <h1>Default Content</h1>
 </ui:insert>
 </div>
 </f:view>
</h:body>
</html>

The template pages must be placed in the web root directory as this technology is simply supported, but has nothing to do with MVC 1.0. So your directory structure in you MVC 1.0 application will look like this:

webapp/
├── layout/
│  ├── my.css
│  └── template.xhtml
└── WEB-INF/
   ├── beans.xml
   ├── faces-config.xml
   ├── web.xml
   └── views/
      │── welcome.xhtml
      └── shopping-cart.xhtml

My Personal Conclusion…

Working with the new MVC 1.0 Web Framework can simplify you application development dramatically. And even if you have a lot of legacy JSF code, don’t worry that all your work is lost. I am currently developing a MVC 1.0 web application in Imixs-Wokflow project and migrating a lot of Facelets and CDI code from an existing application. It’s incredible how simple and clear the concept of MVC 1.0 is. It’s fun to write this kind of Web applications, particularly that its design is fully integrated into JAX-RS which is in most cases also part of your Rest API. And best of all, browser navigation is finally no longer a challenge….

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.