Free Online Courses for Software Developers - MrBool
× Please, log in to give us a feedback. Click here to login
×

You must be logged to download. Click here to login

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

×

MrBool is totally free and you can help us to help the Developers Community around the world

Yes, I'd like to help the MrBool and the Developers Community before download

No, I'd like to download without make the donation

Getting Started with Action-oriented MVC on Java EE 8

Get to know the MVC 1.0, a new JSR that integrates the well-known Action-oriented MVC pattern into the Java EE architecture

Many of the present developers haven’t experienced the beginning of the web development, emerged 20 years ago, when languages like ASP (Active Server Pages) and PHP (Hypertext Preprocessor) were the principal alternatives for building applications in this new environment. Back in those days, when developers were still getting used to this new paradigm and just a few patterns were known and used, it was very common to stumble upon what we nowadays commonly call spaghetti code; a kind of code where presentation and business logic are entangled in a single file. Even worse, many languages would be used too, ending up with a code that mixes HTML, Javascript, ASP/PHP, and CSS.

If you have already faced the unpleasant task of maintaining this kind of code then you know how boring and difficult it is. Its complexity makes it almost impossible to apply core reusability concepts such as encapsulation. A response to this problem was proposed in the form of frameworks, all of them mainly aiming reusability and maintainability. Essentially, the main idea behind those frameworks is that you should create your applications as a composition of layers, where each layer is responsible for a specific task, like business, presentation, and persistence.

Among many patterns used by those frameworks, the MVC (that stands for Model-View-Controller) quickly became the most popular and since its creation the majority of the web frameworks have been choosing it as their favorite pattern. However, if you search over the Internet for the term “MVC”, you will find out that this pattern currently has a lot of variations. Especially in the Java world the variations named Component-based MVC and Action-based MVC are the most common.

As soon as Java debuted in the web development scene, it was also very usual to see many spagheti codes written in JSP around the Internet. Nevertheless, the Java community quickly gave a response to this problem creating frameworks like Struts, Tapestry, JSF, and many others. Since then, this pattern has been widely adopted as the main pattern by many Java web frameworks and a new JSR will be created to represent it in the upcoming Java EE 8.

In this article, we are going to introduce you to this new JSR through a practical example using Ozark, the JSR reference implementation. It’s a Store application where we will be able to add, edit, list, and remove products. Our objective in this article is to discuss this new JSR, showing you its concepts and ideas. However not spending much time in details about any other technology like persistence frameworks.

MVC and its variations

The MVC was proposed back in the 1970s by Trygve Reenskaug and was originally developed to be applied in the Smalltalk language. At first, it was designed to help the development of desktop applications. However, when the web emerged, it was also adopted by a bunch of web frameworks, all of them written in almost all available languages. Because of its importance, Martin Fowler once stated that “as we look at MVC it's important to remember that this was one of the first attempts to do serious UI work on any kind of scale”.

Since its inception, the MVC’s main focus has been to create applications through the composition of logical layers, making clear each layer responsability. For example, the code responsible for persisting objects in a database cannot be mixed up with a code which responsibility is to display UI components in the screen.

Basically, this pattern proposes three layers: Model, View, and Controller. The Model layer is responsible for the business logic and must be completely independent from the View layer, so that it would be reused with any other View technology. In the other hand, the View layer is responsible for displaying data from the Model layer and sending user actions to the Controller. For example, showing input boxes in the screen and forwarding button clicks to by handled by Controller. Lastly, we have the Controller layer, which is responsible for responding to events, or actions, originated from the user interaction with the UI components, like keyboard or mouse inputs. It works like an intermediate between the Model and View, because, as we’ve already said, both cannot have direct interaction.

The MVC pattern has been evolving during all these years and many variations have been created, each one trying to solve different problems. However, even though these variations have many distinct aspects, they take their core principles from the Separated Presentation pattern. This pattern is the foundation for all those patterns and the basic idea behind it is that the business layer must be completely independent from the view layer, as we have already discussed.

Nowadays, we have many patterns extending the MVC core concepts: MVP (Model-View-Presenter), MVA (Model-View-Adapter), AM-MVP (Application Model – Model View Controller), and etc. Recently, two new flavours aiming the web environment were suggested by the community: Action-based MVC and Component-based MVC.

Component-based MVC

In this pattern, our UI is completely made of a composition of components and a framework whose core responsibility is hidding from developers the logic that handles the HTTP request and response flow. In this scenario, for example, the programmer doesn’t need to spend any effort on maintaining the application state along multiple requests. Even better, the programmers do not need to know anything about Javascript to take the advantage of using AJAX calls in their applications.

Below are some of the responsibilities that a framework based on this pattern has:

  • Make URL creation transparent to the developer;
  • Store the application state among multiple calls;
  • Isolate the developer from HTTP handling;
  • Provide UI components.

In the Java world, the first framework to adopt this pattern was Apache Tapestry, followed close behind by Java Server Faces, which is currently the most used Java web framework. One of the main advantages of using this kind of framework is the ease of use that the composition of components provides us, such as reuse and better maintainability. However, some may argue that its curve of learning is relatively long, even though, once it’s learned, the application becomes easier to maintain.

Another benefit brought by the use of components is the fact that developers are able to create an application with almost no knowledge about HTML, Javascript, and CSS, because components encapsulate the logic needed to show these elements in the screen and handle the events fired by those elements, such as an input text or a list.

Nevertheless, this pattern isn’t immune to criticism. Martin Fowler, a stark critic of this pattern, made harsh criticism regarding JSF and its problems. In a Technology Radar issue, a ThougthWorks publication (his own company), he commented that JSF forces, with no success, statefull applications through a stateless protocol, in this specific case, the HTTP protocol. He continues saying that this protocol wasn’t created with persistent state applications in mind, which causes problems regarding the shared state in the server side.

Action-based MVC

Quite different from the Component-based MVC, this pattern doesn’t try to keep the developers distant from the HTTP peculiarities and to keep them off languages like Javascript, HTML, and CSS. So, this pattern doesn’t aim to provide components, such as input texts, that we would use to build an UI with no knowledge about HTML.

An action-based MVC framework just redirects HTTP requests to a specific controller that is choosen out of the data carried by these requests. The choosen controller is responsible for defining which action must be taken, for example, updating a Model, and which HTTP response must be given. As we can see, this pattern gives the developers full responsibility over their applications, even though it forces the developer to learn what is happening under the hood in the HTTP protocol.

When using this pattern, we are not locked in to a specific presention technology. For example, we are free to choose among many Templating frameworks, like FreeMarker, Mustache, and many others. We are even able use JSP, if we wish. The first Java framework to adopt this pattern was Apache Struts, widely used in the early days of Java web development. It was followed by Spring MVC and VRaptor. Nowadays, we have a lot of frameworks that use this pattern.

MVC 1.0

The JSR 371, or just MVC 1.0, will debut in the new Java EE 8, planned to be released in Q3 2016. By that time, there’s a long way ahead and many changes can occur. However, at the moment, we already have an idea about how this JSR is going to be, because the Reference Implementation, called Ozark, is already available for use. This let us create an application and see this JSR in action.

Talking about a possible competition between JSF and MVC 1.0, both teams have already said that the later isn’t comming to replace the former. JSF still has a long life ahead and there isn’t any plan about abandoning its development. Actually, the new JSR 371 comes to allow developers to build applications using this pattern along with all other Java EE specs, like CDI and Bean Validation.

JAX-RS

As we will see in the following sections, the MVC 1.0 makes extensive use of JAX-RS, the JSR created to build RESTful web services in Java. In fact, JAX-RS was used as the MVC 1.0 foundation because it already provides many of the features it requires. As a result, the API of this new JSR is packed with just a few classes, interfaces, and annotations.

We believe this is a desirable aspect, since JAX-RS has been in the market for a long time, is well-known, widely adopted by the community, and is fully mature. As you will see in this article, all concepts surrounding JAX-RS fit perfectly in the MVC use cases, with no functionality overlaping.

The Store

To demonstrate the use of this new JSR, we are going to create a simple Store application, where we’ll be able to add, update, delete, and list products. As you can see, it contains only CRUD (Create, Retrieve, Update and Delete) operations. We’ll build such a simple application because our main focus in this article is showing the JSR 371 main concepts and characteristics.

Ozark and Glassfish

The first step necessary to build our application is to get and install Ozark, the JSR reference implementation. In order to accomplish it, we have two options available: download the JAR file in Ozark site or use a dependency management tool like Maven or Gradle. In this article, we’ll follow the Maven path, so just add the lines presented in Listing 1 inside the dependencies section of your pom.xml file,.

Listing 1. Ozark Maven dependency.

com.oracle.ozark
<p align="left"> ozark
<p align="left"> 1.0.0-m01
<p align="left"> compile

Now, we need a Java EE container so that we can run our example. For this purpose, we will need a special Glassfish version, because MVC 1.0 is not available for use in the present Java EE containers. It’s a development version, commonly named Nightly Build, and you can get its address at the Links section. Once you’ve downloaded it, just decompress it and execute it.

Project structure

We are going to use Eclipse Mars.1 as our IDE, however, because this is a Maven-based project, and you can interact with Maven through the command line, you are free to use any IDE of your choice. In your IDE, create a new Maven-based project and remember to add the lines shown in Listing 1 in your pom.xml file. Also ensure that the WAR option in the Packaging listing has been selected. Afterwards, create a package structure like the one shown in the Figure 1. In this figure, we have the package com.mrbool.controller, where we’ll put all classes representing the Controller layer, and com.mrbool.model where we’ll store all classes representing the Model layer.

Figure 1. Project structure.

Representing a product

Our first step is to create a class that represents a product in our application. We will try to create it as simple as possible, avoiding bloating this article with unnecessary code. Thereby, create a class like the one shown in the Listing 2, where we have a class called Product inside the package com.mrbool.model. This class is made up of four atributes: code, price, name, and description. Note that we have ommited all getters and setters methods, therefore don’t forget to add them yourself.

Listing 2. Product class.

package com.mrbool.model;

import java.util.ArrayList;
import java.util.List;

public class Product {
 private String code;
 private String name;
 private Double price;
 private String description;
 private static List list = new ArrayList();

 static {
 list.add(new Product("B1", "Weiss", 6.50, "Weiss Beer"));
 list.add(new Product("B2", "Pilsen ", 4.50, "Pilsen Beer"));
 list.add(new Product("B3", "Stout", 16.50, "Stout Beer"));
 list.add(new Product("B4", " IPA", 12.50, "IPA Beer"));
 }

 public Product() {
 }

 public Product(String code, String name, Double price, String description) {
 this.code = code;
 this.name = name;
 this.price = price;
 this.description = description;
 }

 public static List list() {
 return list;
 }
}

Observe in this class that we have added a new constructor in addition to the default constructor just to make it simple to create instances from it. We’ll also need a static instance of java.util.List to work as a persistence storage. In order to initialize this list, we created a static block that will be executed as soon as our application starts. In this block, we created four products and added them to this list. Finally, we have a static method named list(), that will return the list of products.

Entrypoint

One of the first tasks needed when building a MVC 1.0 application is to create a class that extends javax.ws.rs.core.Application to work as our entrypoint. It is important because we must use it to provide additional metadata to the JAX-RS engine, like the URI template, that can be provided through the @javax.ws.rs.ApplicationPath annotation, as shown in Listing 3.

Listing 3. Application class.

package com.mrbool;

import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("web")
public class StoreApplication extends Application {
}

What’s also important to note is that we are passing the parameter “web” to the @javax.ws.rs.ApplicationPath annotation in order to tell JAX-RS that our template URI will follow the pattern http:////web/, where:

  • must be replaced by your server address or domain;
  • must be replaced by the servlet context of your application and
  • must be replaced by the resource being accessed.

First Controller

Before we go any further, we need to clarify what a Controller is. In MVC 1.0, a controller is responsible for receiving and handling HTTP requests in accordance with the underlying application business rules. What this means is when an user accesses an URI from your application, an object, or even a method, will be notified that someone is asking to access a specific feature (editing a product, for example). As a consequence, this object or method will carry on some tasks, like invoking business methods and, lastly, redirecting the user to a view.

To make this idea even more clear, imagine a situation where an user accesses an URI in order to edit a product. In this case, the following tasks will be respectively performed: MVC 1.0 will detect which controller should handle it, the controller will ask the business layer to retrieve the product from the database layer, and redirect the user to a page where product data will be shown.

Now that we have clarified these ideas, let us create our first controller. As you can see in the Listing 4, it has been named ProductController and allows our users to manage a product. Note that this is a really simple class, because it doesn’t need to extend from a parent or even implement any interface. All we need to do is annotate it with @javax.ws.rs.Path to identify the base URI path to which this controller will respond. The @Path annotation’s value is a partial URI path template relative to the base URI of the server on which our application is deployed, the context, and the URI pattern to which JAX-RS responds. In this specific case, this method will respond to the URI path http:////web/products.

Listing 4. ProdutoController class.

package com.mrbool.controller;

import javax.inject.Inject;
import javax.mvc.Controller;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

import com.oracle.ozark.core.Models;

import com.mrbool.model.Product;

@Path("products")
public class ProductController {
 
 @Inject
 private Models models;
 
 @Controller
 @GET
 public String list() {
 models.put("products", Product.list());
 return "/WEB-INF/jsp/list.jsp";
 }

}

Moving on, let’s take a closer look at the models attribute, that has the type com.oracle.ozark.core.Model, a native Ozark class that implements the javax.mvc.Models interface. This kind of object is responsible for transporting objects from Controllers to Views and are useful in scenarios where we want to display data from models in our views. Another important aspect is that we are not directly instantiating this attribute. Instead, we are injecting an instance of it using @javax.inject.Inject annotation from CDI.

Note: Just remember that to get the CDI working, we must have the beans.xml inside the WEB-INF directory.

Now, let’s pay attention to the list() method, that is receiving two annotations: @javax.mvc.Controller and @javax.ws.rs.GET. The first annotation tells MVC engine it is a Controller method and is responsible for receiving and handling HTTP requests. Only methods annotated with it are eligible to handle HTTP requests. It’s also a class-level annotation and when used that way all public methods within the class become controllers.

The second annotation is a request method designator and corresponds to the similarly named HTTP method. It forces the method list() to process only HTTP GET requests, ignoring all other request types (POST, PUT, DELETE, and so on). Note that we haven’t used the @Path annotation to determine the relative URI path to this method. In this case, any GET request that arrives at the /web/products path will be handled by list(). We also added the product list to the models attribute and returned a String containing the path to the JSP page that is responsible for displaying the product list.

Note: Have you noticed that the put() method from com.oracle.ozark.core.Models is identical to the put() method from java.util.Map?In fact, this class was implemented by the Ozark team as a layer above the java.util.Map and it just transfers all calls to its methods to a similar method on an internal java.util.Map instance.

Listing 5. JSP responsible for displaying products data.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
 <head></head>
 <body>
  <h1>Products</h1>
 
  <div>
   <table>
    <c:forEach var="product" items="${products}">
     <tr>
      <td>${product.code}</td>
      <td><a href=" products/edit/${product.code}">${product.name}</a></td>
      <td>${product.price}</td>
      <td>${product.description }</td>
     </tr>
    </c:forEach>
   </table>
   <br>
   <form method="GET" action="products/new/">
    <button type="submit">New</button>
   </form>
  </div>
 </body>
</html>

Lastly, Listing 5 shows the JSP code responsible for displaying a list of products, in this case, represented by the products variable. We used the c:forEach tag that iterates over each product in this list, showing its data, as you can see in Figure 2. We also have a button that redirects the user to the edit page.

Figure 2. Listing page.

Adding a product

Now that we have a working listing page, we can move on and allow our users to add new products. To make it possible, we have to modify some classes and create a new JSP page containing a form. As our first task, let’s change our ProductController class, adding two new methods to it (shown in Listing 6).

Listing 6. New ProductController class methods.

 @Path("new")
 @Controller
 @GET
 public String preAdd() {
  return "/WEB-INF/jsp/edit.jsp";
 }
 
 @Path("new")
 @Controller
 @POST
 public String insert(@BeanParam Product product) {
  Product.add(product);
  models.put("products", Product.list());
  return "/WEB-INF/jsp/list.jsp";
 }

The first method, named preAdd(), has no parameters and only redirects users to an edit page. This method will respond only for GET requests, what justifies the @GET annotation we added to it. In its body, we are just returning the path where the JSP page containing the form is located.

The second method has been named insert(Product) and just adds the product passed as a parameter to it to our internal list through the add() method, located at the Product class (we’ll see it soon). Because we want it only responding for HTTP POST requests, we added the annotation @POST to it. Note that the single parameter it receives is annotated with @javax.ws.rs.BeanParam, that belongs to JAX-RS. In MVC 1.0, it works exactly the same way as it works in JAX-RS: we must use it when we need to receive a POJO in a controller. In this specific case, an instance of Product will be created and its attributes will be filled with the request data.

Figure 3. Adding a product.

However, until now we haven’t defined how this instance attributes are going to be filled. For example, which value should be assigned to the name attribute? Remember that the request arrives at the controller carrying data from forms and the Query String; hence, we need to instruct Ozark how it should fill the object attributes using these values. That’s when the @FormParam annotation comes into play. We’ll use it to associate a form value to an object attribute, as shown in the Listing 7. For example, in this listing we are associating the form value called name to the atribute also called name in the Product class.

In the method’s body, we are adding the product to our internal list invoking the method add(Product) from the Product class. We are also putting the product list into the models object and redirecting the user to the list page. Now let us finalize this feature creating the add(Product) method inside our Product class as shown in Listing 7, where we are including the product passed as paramenter to our internal product list.

Listing 7. Using @FormParam annotation.

public class Product {
             
 @FormParam("code")
 private String code;
 
 @FormParam("name")
 private String name;
 
 @FormParam("price")
 private Double price;
 
 @FormParam("description")
 private String description;
 
 public static void add(Product product) {
  list.add(product);
 }
 
}

Finally, we need a form so that our users could be able to create new or edit existing products. Thereby, create a file inside the /WEB-INF/jsp directory and name it edit.jsp. Now, put the code at the Listing 8 as its content, where we have a form and an input text to each product attribute. Note that the form method attribute must be defined as POST and the action attribute must be empty, because we want this form being submitted to the current URI. Once finished, this page will look like the one shown in Figure 3.

Listing 8. JSP page containing the Product edit form.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<body>
 <h1>Product</h1>
 
 <div>
  <form method="POST" action="">
   Code: <input type="text" name="code" id="code" value="${product.code}"/><br>
   Name: <input type="text" name="name" id="nome" value="${product.name}"/><br>
   Price: <input type="text" name="price " id="preco" value="${product.price}"/><br>
   Description: <input type="text" name="description" id=" description" value="${product.description}"/><br>
   <button type="submit">Send</button>
  </form>
 </div>
</body>
</html>

Do you remember that we used the @FormParam annotation in the previous sections and associated each attribute with a form value? Now, things are becoming more clear? Note that in this form, the value attribute of each input tag references a product value so that a product variable holding the values inserted by the user in these fields will be created and passed to the controller method responsible for handling this request. However, because this variable doesn’t exist yet, it is empty and when the user accesses this form for the first time, it will be shown empty also.

Editing products

The next feature we are going to implement in this section will let people manage a product. Therefore, we’ll need, once more, to edit some classes and files in our project. Let’s start creating two new methods in the ProductController class, as shown in Listing 9.

Listing 9. ProdutoController new methods.

 @Path("{code}")
 @Controller
 @GET
 public String preEdit(@PathParam("code") String cod) {
  models.put("product", Product.get(cod));
  return "/WEB-INF/jsp/edit.jsp";
 }
 
 @Path("{code}")
 @Controller
 @POST
 public String edit(@PathParam("code") String code, @BeanParam Product product) {
  Product.edit(product);                      
  models.put("products", Product.list());
  return "/WEB-INF/jsp/list.jsp";
 }

In this listing, in both methods, have you noticed that we are accessing URI path parameters in our controllers? And why do we need it? Because in order to modify a product, first off, we need its identifier, otherwise, we won’t be able to retrieve it from our database and consequently show it in a form. One possible way to pass this identifier to a controller is through the URI path, where an user asks to modify a product passing the product identifier in the URI address as in http://<youdomain>/<context>/web/products/B1, where B1 is the product identifier.

Figure 4. Modifying a product.

The last question to be answered is “how can I have access to this URI variable in MVC 1.0?”. If you’ve already used JAX-RS then you know it’s going to be a really simple task, because under the hood MVC 1.0 uses the JAX-RS mechanisms to do it. To embbed variables within the URI syntax, we need to use the @Path annotation and surround a value with curly braces. This is exactly what we did in the Listing 9, through the method preAdd(). Note that we are surrounding the value code with curly braces in order to tell JAX-RS that it’s a variable. From now on, this method will respond for all GET requests that arrive at the following URIs:

· http:// <youdomain>/<context>/web/products/B1;

· http://<youdomain>/<context>/web/products /ABC1;

· http:// <youdomain>/<context>/web/products /123456.

However, this is not enough, because we still don’t have the path variable’s value in our hands. For this task, we have to associate a method parameter with a path variable. Therefore, we must annotate a method parameter with @PathParam such as we did in the Listing 9, where we associated the String parameter named cod with the URI variable named code. Finalizing this method, we are retrieving the product, putting it in the model attribute and redirecting the user to the edit page that, as you can see in Figure 4, is the same page we’ve used to add a product.

To conclude this feature, we’ll add a method called edit(), which has two parameters: the first one is the product code and the second one is an instance of Product containing the changes made by an user using the edit form. In this method, we are using the same mechanisms we used in the insert() method, as you can see in the method preEdit() presented in the Listing 6. In the method body, we are invoking the edit() method from Product, as shown in the Listing 10.

Listing 10. Novo método para atualizar produtos.

  public static void edit(Product product) {
  Product e = get(product.code);
  e.code = product.code;
  e.description = product.description;
  e.name = product.name;
  e.price = product.price;
 }

Validation

What should we do when an user tries to persist a product with a null value assigned to the name attribute? Should we accept negative values for a product price? Of course, it depends on the underlying business rules but, in this article, we’ll add some constraints to show you how to integrate the Bean Validation into the MVC 1.0.

We’ll start changing the Product class in order to add some annotations to it. These changes are in the Listing 11, where you can see @javax.validation.constraints.NotNull and @javax.validation.constraints.Min annotations. The former must be used to determine that null values can’t be assigned to a attribute and the later must be added to an attribute when we need to define a maximum value that it can hold.

Listing 11. Using Bean Validation.

public class Product {
 
 @FormParam("code")
 @NotNull
 private String code;
 
 @FormParam("name")
 @NotNull
 private String name;
 
 @FormParam("price")
 @NotNull
 @Min(0)
 private Double price;
 
 @FormParam("description")
 private String description;
}

Now, we need to make some changes in our ProductController class, as shown in Listing 12. We started injecting an instance of javax.mvc.validation.ValidationResult into the validationResult attribute. This injected object will hold the validation result and we use it to determine whether the validation was succesful or not.

Listing 12. Modifying ProdutoController to use Bean Validation.

@Path("products")
public class ProductController {
 
 @Inject
 private ValidationResult validationResult;
 
 @Path("new")
 @Controller
 @POST
 @ValidateOnExecution(type = ExecutableType.NONE)
 public String insert(@BeanParam @Valid Product product) {
  String result = "/WEB-INF/jsp/list.jsp";
 
  if (validationResult.isFailed()) {
   models.put("errors", validationResult.getAllViolations());
   models.put("product", produto);
   result = "/WEB-INF/jsp/product.jsp";
  } else {
   Product.add(product);
   models.put("products", Product.list());
  }
 
  return result;
 }
}

You might have noticed that we added the annotation @javax.validation.executable.ValidateOnExecution to the method which will perform the validation to inform that the validation will take place when the request starts. We also need to annotate the parameter product with @javax.validation.Valid in order to notify that this parameter contains Bean Validation annotations and must be validated. Now, we are able to use the method isFailed() from the validationResult object and check whether all validations passed or not. In Listing 12, note that when we detect a failure, we put the associated errors list in the model object, hence we can access it in the edit.jsp page and show it to the user, according to Listing 13.

Listing 13. Displaying errors on edit.jsp.

  <table>
   <c:forEach var="erro" items="${errors}">
    <tr>
     <td style="color: red">${error.message}</td>
    </tr>
   </c:forEach>
  </table>

Handling Exceptions

Suppose an unexpected error has occured or maybe an unexpected action has been taken by an user, such as accessing an URI to edit a non-existing product. What should we do in such occasions? Should we just let the default error screen pop up, showing the Java exception stack? Obviously, the answer is no. But, how can we handle exceptions in our application in such a way that all errors would be captured and handled in a centralized point?

To help us face this kind of problem, JAX-RS provides us with Exception Mappers, which are objects that capture unhandled exceptions (exceptions not handled by try-catch blocks). To show you how to use it, we will change the Product class and make the get() method throw an exception named ObjectNotFoundException, as shown in Listing 14. This exception will be thrown whatever an user calls it passing an invalid product code.

Listing 14. Changing get() in Product class.

 public static Product get(String code) {
  Product result = null;
 
  for (Product product : list) {
   if (product.code.equals(code)) {
    result = product;
    break;
   }
  }
 
  if (result == null) {
   throw new ObjectNotFoundException();
  }
 
  return result;
 }

Note that we won’t change the controller class to catch this exception. Therefore, this error will be bubbled up in the call stack until it reaches a try-catch block responsible for handling it or blow up your program and show the stack trace in the screen. If you are curious about how the application will behave right now, without an Exception Mapper, just execute it and see it in action.

Because we don’t want our application showing this ugly error screen, we’ll create an Exception Mapper to handle exceptions of the type ObjectNotFoundException. First off, we need to create a class named ObjectNotFoundExceptionMapper, as shown in Listing 15, and annotate it with @javax.ws.rs.ext.Provider to make it visible to the JAX-RS engine. We also need to make it implement the javax.ws.rs.ext.ExceptionMapper interface, what forces us implement the toResponse() method.

Listing 15. ObjectNotFoundException class.

package com.mrbool;
 
public class ObjectNotFoundException extends RuntimeException {
 private static final long serialVersionUID = 1L;
 
}

In the toResponse() method body, shown in Listing 16, we are returning a Status.BAD_REQUEST response, which corresponds to the 400 Error code, putting the error array in the models object, and redirecting the user to an error page named error.jsp. From now on, every time an ObjectNotFoundException exception is thrown and not properly handled by a try-catch block, this class will be invoked and the user redirected to the error.jsp page.

Listing 16. ObjectNotFoundExceptionMapper class.

@Provider
public class ObjectNotFoundExceptionMapper implements ExceptionMapper<ObjectNotFoundException> {
 
 @Override
 public Response toResponse(ObjectNotFoundException exception) {
  return Response
    .status(Status.BAD_REQUEST)
    .entity("/WEB-INF/jsp/error.jsp")
    .build();
 }
 
}

@View annotation

You might have noticed that every method we have created until now redirects the user to a page. We did it just returning a String containing the path to a JSP page. This is an interesting way that can be used when the page is dinamically defined, for example, when it depends on a specific user action. We have used this tactic in two methods: insert() and edit().

However, note that we have two other methods that always redirect the user to the same page, regardless of the user actions. In this case, we can use the @javax.mvc.View annotation, passing the page path as its value, according to the Listing 17. Note that when using this annotation, the method doesn’t need to return a String anymore, what is the reason why we changed the method return type from String to void.

Listing 17. Using @View annotation.

 @Controller
 @GET
 @View("/WEB-INF/jsp/list.jsp")
 public void list() {
  models.put("products", Product.list());
 }

There are two other ways to tell MVC which page to display: returning a javax.ws.rs.core.Response instance, like we did in ObjectNotFoundExceptionMapper class, or returning a javax.mvc.Viewable instance. Listing 18 depicts how to use the Response class, where we changed the edit() method to return a instance of this class. Lastly, in the Listing 19, we changed the insert() method to return a Viewable object.

Listing 18. Returning a Response object.

 @Path("{code}")
 @Controller
 @POST
 @ValidateOnExecution(type = ExecutableType.NONE)
 public Response editar(@PathParam("code") String codigo, @BeanParam @Valid Product product) {
  String result = "/WEB-INF/jsp/list.jsp";
 
  if (validationResult.isFailed()) {
   models.put("errors", validationResult.getAllViolations());
   models.put("product", product);
   result = "/WEB-INF/jsp/edit.jsp";
  } else {
   Product.edit(product);
   models.put("products", Product.list());
  }
 
  return Response.status(Status.OK).entity(result).build();
 }

Listing 19. Returning a Viewable object.

 @Path("new")
 @Controller
 @POST
 @ValidateOnExecution(type = ExecutableType.NONE)
 public Viewable insert(@BeanParam @Valid Product product) {
  String result = "/WEB-INF/jsp/list.jsp";
 
  if (validationResult.isFailed()) {
   models.put("errors", validationResult.getAllViolations());
   models.put("product", product);
   result = "/WEB-INF/jsp/edit.jsp";
  } else {
   Product.add (product);
   models.put("products", Product.list());
  }
 
  return new Viewable(result);
 }

Template Engines

If you have been developing in Java for a long time, then you have probably worked with a template engine. For those who never worked with it, these engines are responsible for processing templates, composed of HTML markup and special instructions recognized only by the engine. For example, a template engine replaces an instruction like ${product.name} with the value of the name attribute.

Even though JSP is the default choice in MVC 1.0, we are not tied to this technology, because we are able to use some template engines available in the market, like Velocity, Mustache, FreeMarker, Handlebar, Thymeleaf. For example, if you want to use Mustache instead of JSP, you just need to add the Ozark Mustache dependency as shown in Listing 20. Once you added this dependecy to your pom.xml, you are now able to return a view containing Mustache directives.

Listing 20. Adding Mustache support in our pom.xml.

<dependency>
    <groupId>com.oracle.ozark.ext</groupId>
    <artifactId>ozark-mustache</artifactId>
    <version>1.0.0-m01</version>
    <scope>compile</scope>
</dependency>

Handling Events

Although it’s not commonly used in business solutions, MVC 1.0 fires its own events through the CDI and that can be captured by you using the @javax.enterprise.event.Observes annotation. For example, we can intercept these events to persist log data about the application execution in order to identify the reasons behind an error that may occur in runtime. Another possible use for it, is to detect which features are more accessed by our users, integrating our system with Google Analytics.

Listing 21. Handling events.

public class Log {
 
 public void log(@Observes ControllerMatched event) {
  System.out.println("Match: " + event.getResourceInfo().getResourceMethod());
 }
 
}

Listing 21 shows us how to intercept this event through the class named Log. In this class, we created a method called log(), which has a parameter of the type ControllerMatached and is annotation with @Observes. This method will be invoked every time a controller is identified as responsible for handling a request.

Conclusion

MVC 1.0 offers us one more way to build web applications in Java EE. Previously, JSF was the only option available for us but, soon, we’ll also be able to use the Action-based MVC to develop our applications. It’s a important step toward an wealth Java ecosystem, because nowadays developers have their hands tied and cannot use any other option besides JSF.

Integrating the MVC pattern into the Java EE environment becomes even more important because the interest on frameworks like Spring MVC and VRaptor has been increasingly rising, what denotes that this pattern is important and has been used for a long time by Java developers. This new JSR will engage the development of new frameworks, increasing the range of options available for the Java developer, that will be able to choose the best option for your needs.

Lastly, even though this API isn’t yet released, we can see how it’s going to look like through the Ozark project, its reference implementation. Knowing this JSR before its release, even though its in a unstable state, is important because you’ll be able to foresee how this JSR will affect you future projects.

Links

MVC 1.0.

https://www.jcp.org/en/jsr/detail?id=371

Ozark.

http://ozark.java.net

Separated Presentation.

http://martinfowler.com/eaaDev/SeparatedPresentation.html

Spring MVC.

https://spring.io/

GlassFish Nightly Build.

http://dlc.sun.com.edgesuite.net/glassfish/4.1/nightly/glassfish-4.1-b13-03_16_2015.zip



colunista nao disponivel

What did you think of this post?
Services
[Close]
To have full access to this post (or download the associated files) you must have MrBool Credits.

  See the prices for this post in Mr.Bool Credits System below:

Individually – in this case the price for this post is US$ 0,00 (Buy it now)
in this case you will buy only this video by paying the full price with no discount.

Package of 10 credits - in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download few videos. In this plan you will receive a discount of 50% in each video. Subscribe for this package!

Package of 50 credits – in this case the price for this post is US$ 0,00
This subscription is ideal if you want to download several videos. In this plan you will receive a discount of 83% in each video. Subscribe for this package!


> More info about MrBool Credits
[Close]
You must be logged to download.

Click here to login