Enterprise Java

MVC 1.0 in Java EE 8: Getting started using facelets

MVC 1.0 is an action-based Model-View-Controller web framework, which will be a part of future Java EE 8. It will live side by side with component-based JSF framework and will provide an alternative for building HTML+javascript oriented applications with full control over URLs.

This post summarizes what needs to be done in order to use Facelets instead of default JSP as a view technology for MVC framework.

Introduction

Although MVC is a fresh new framework, the default view technology used in most examples – JSP – is rather old and sometimes cumbersome. On the other hand, the older brother JSF already builds on more modern and flexible Facelets.

Fortunately, MVC framework has been designed to support many alternative view technologies out of the box, including Facelets.

Getting started

Although Java EE 8 is not yet released, it is possible to use MVC framework already in some Java EE 7 servers, as the reference implementation of the MVC specification named Ozark is already almost complete.

Ozark is reported to work with application servers Glassfish 4.1.1 and Payara 4.1. I recommend to run the application on one of them otherwise you risk some glitches here and there.

Until Java EE 8 is released, it is necessary to add dependency on ozark maven artifact with default scope compile on top of Java EE 7 API:

Dependencies in pom.xml

    <dependency>
      <groupId>javax</groupId>
      <artifactId>javaee-web-api</artifactId>
      <version>7.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.glassfish.ozark</groupId>
      <artifactId>ozark</artifactId>
      <version>1.0.0-m02</version>
      <scope>compile</scope>
    </dependency>

That’s all what is needed to set up the project. You are now ready to use new MVC framework with Java EE!

Controller

MVC framework is built on top of JAX-RS and integrates with CDI and Bean Validation. Hence, MVC Controller is a JAX-RS resource, just annotated with @javax.mvc.annotation.Controller:

HeloController.java

@Path("/hello")
@Controller
@RequestScoped
public class HelloController {
 
    @Inject
    private Models model;
    
    @GET
    public String doGet() {
        model.put("hello", "Hello MVC 1.0");
        
        return "hello.xhtml";
    }
}

The controller contains business logic and glues a model to a view in result.

The view is simply identified by the string returned from controller action. To use facelets, it is enough to specify a path, which will be mapped to the Facelets servlet (we use xhtml suffix by convention).

The model is represented by injected Models object.

A few things to note here. First, as the controller is a JAX-RS resource, it is necessary to create also JAX-RS application configuration – a class that extends javax.ws.rs.core.Application.

Second, unless you include beans.xml with bean discovery mode all, you need to mark your controller with a scope-defining annotation, like @RequestScoped, to turn on CDI injection of Models model.

Model

The model consists of objects identified by String keys, which are turned into variables in the view page.

There are 2 ways how to define the model. The first is to inject javax.mvc.Models into the controller, which is effectively a map. The controller action then puts objects into the injected model under String keys.

JSP and Facelets support also arbitrary CDI beans marked with @Named CDI qualifier. This way, you may turn any CDI bean into a model just by putting the @Named annotation on it.

View

And now to the core of this post – we will use facelets to display data in our model. In fact, using Facelets as the view technology is equally easy as using JSPs. It only requires to setup the Facelets servlet properly.

FacesServlet configuration in web.xml

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>

FacesServlet needs to be mapped to *.xhtml. All xhtml pages should reside inside WEB-INF/views folder inside the web application, where the MVC framework searches for view files.

And that’s it! Now, you may start writing pages using facelets and reference them by path, which ends in xhtml.

An example Hello facelet page:

hello.xhtml

<?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://xmlns.jcp.org/jsf/html">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <h1>#{hello}</h1>
    </h:body>
</html>

In order to display hello.xhtml, just return "hello.xhtml" from the controller action and you’re done.

Summary

Getting started with MVC framework is really easy once you understand basics of JAX-RS and CDI. The only requirement is to run your application on one of the application servers that support Ozark reference implementation. It is also very easy to use various view technologies as alternatives to default JSPs.

MVC framework includes support for many view technologies and enables to plug in other technologies on top of it. Configuring Facelets required only to configure Faces servlet in web.xml – the same thing you need to do when setting up JSF.

This post was inspired by another post by Bennet Schulz. Visit his blog if you want to read more about the new MVC framework.

Ondrej Mihalyi

Ondrej is a lecturer and consultant inventing and evangelizing new approaches with already proven Java tooling. As a Scrum Master and expert in Java EE ecosystem, he helps companies to build and educate their developer teams, improve their development processes and be flexible and successful in meeting client requirements.
Subscribe
Notify of
guest

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

0 Comments
Inline Feedbacks
View all comments
Back to top button