Understanding Jsf as a MVC Framework

Understanding JSF as a MVC framework

Part of the reason why it's often not entirely clear in JSF and many other web frameworks which parts of it correspond to which part of MVC, is that the MVC pattern was originally devised for desktop applications.

In a desktop application, the nodes M, V and C are a maximum connected graph, meaning each part can communicate with every other part. E.g. if the model changes, it can push this change to the view. This is particularly visible in case there are multiple representations of the view in a desktop application. Change one, and see the other update in real-time.

Due to the client/server and request/response nature of web applications, classic MVC doesn't map 1:1 to most web frameworks.

Specifically, in JSF the mapping is as follows:

  • Model - The Services/DAOs plus the entities they produce and consume. The entry point to this is the managed bean, but in Java EE (of which JSF is a part) these artifacts are typically implemented by EJB and JPA respectively.
  • View - The UI components and their composition into a full page. This is fully in the domain of JSF and implemented by JSF UIComponents and Facelets respectively.
  • Controller - The traffic cop that handles commands and incoming data from the user, routes this to the right parts and selects a view for display. In JSF one doesn't write this controller, but it's already provided by the framework (it's the FacesServlet).

Especially the last part is frequently not well understood: In JSF you don't implement a controller. Consequently, a backing bean or any other kind of managed bean is NOT the controller.

The first part (the model) is also not always clearly understood. Business logic may be implemented by EJB and JPA, but from the point of view of JSF everything that is referenced by a value binding is the model. This is also where the name of one of the JSF life-cycle phases comes from: Update Model. In this phase JSF pushes data from the UI components into the model. In that sense, (JSF) managed beans are thus the model.

Although JSF itself doesn't explicitly define the concept, there is an often recurring and specific usage of managed beans called the backing bean.

For JSF a backing bean is still the model, but practically it's a plumbing element that sits in the middle of the Model, View and Controller. Because it performs some tasks that may be seen as some controller tasks, this is often mistaken to be the controller. But, as explained before this is not correct. It can also perform some model tasks and occasionally do some view logic as well.

See also:

  • What are the main advantages of MVC pattern over the old fashioned 3-layer pattern
  • MVC-Architecture of JavaServer Faces (Chapter 4.3)

What components are MVC in JSF MVC framework?

This depends on the point of view (pun intented).

In the big architectural picture, your own JSF code is the V:

M - Business domain/Service layer (e.g. EJB/JPA/DAO)

V - Your JSF code

C - FacesServlet

In the developer picture, the architectural V is in turn dividable as below:

M - Entity

V - Facelets/JSP page

C - Managed bean

In the smaller client picture, the developer V is in turn dividable as below:

M - JSF component tree

V - Rendered HTML output

C - Client (webbrowser)

In the yet smaller JavaScript picture, the client V is in turn dividable as below:

M - HTML DOM tree

V - Visual presentation

C - Event listener functions (enduser interaction and Ajax)

So it's basically a M(M(M(MVC)C)C)C ;)

Note that some starters and even some —very basic— tutorials mingle/copy/flatten the entity's properties in the managed bean, which would effectively make the controller a model. Needless to say that this is poor design (i.e. not a clean MVC design).

The code snippets in the following answers illustrate the right MVC approach:

  • JSF Controller, Service and DAO
  • Creating master-detail pages for entities, how to link them and which bean scope to choose
  • Passing a JSF2 managed pojo bean into EJB or putting what is required into a transfer object
  • Filter do not initialize EntityManager
  • javax.persistence.TransactionRequiredException in small facelet application

In the books The Definitive Guide to JSF in Java EE 8, chapter 8 "Backing beans", page 276, and The Definitive Guide to Jakarta Faces in Jakarta EE 10, chapter 8 "Backing Beans", page 288, the below Venn diagram is used to illustrate the position of the backing bean in the MVC paradigm within the context relevant to the JSF developer. Copyright disclaimer: aforementioned books are written by me and the picture is created by me.

Sample Image

Contradictory explanations of MVC in JSF

I'm mostly concerned about Managed beans here. Are they M or C?

People consider them M when they look like this:

@ManagedBean
public class Bean {

private String username; // +getter+setter
private String password; // +getter+setter

@Resource
private DataSource dataSource;

public void login() {
try (
Connection connection = dataSource.getConnection();
PreparedStatement statement = connection.prepareStatement("SELECT * FROM User WHERE username = ? AND password = MD5(?)");
) {
statement.setString(1, username);
statement.setString(2, password);

try (ResultSet resultSet = statement.executeQuery()) {
if (resultSet.next()) {
// Login.
}
}
}
}

// ...
}

But people consider them C when they look like this:

@ManagedBean
public class Bean {

private User user // +getter

@EJB
private UserService userService;

public void login() {
if (userService.find(user) != null) {
// Login.
}
}

// ...
}

This is also mentioned in the very same MVC answer you found:

Note that some starters and even some —very basic— tutorials mingle/copy/flatten the entity's properties in the managed bean, which would effectively make the controller a model. Needless to say that this is poor design (i.e. not a clean MVC design).

See also:

  • Our JSF wiki page

How does Servlet/JSP MVC patterns translate to JSF/Facelets (in particular the service and controller parts)?

There are two levels of MVC in JSF 2:

  • Model = @ManagedBean, View = Facelets/xhtml, Controller = FacesServlet if you look only at jsf
  • Model = Entities + Services, Controller = @ManagedBean, View = xhtml if you look at your application at a whole.

The typical package layout in a JSF application is the same:

  • com.foo.domain.featurex.service <- model
  • com.foo.domain.featurex.model <- model
  • com.foo.presentation.featurex <- controller
  • xhtml files <- view

Not that big of a difference here except that your controller is now the FacesServlet (the heart of JSF) together with your @ManagedBean/@Named which would reside in a class like com.foo.presentation.featurex.Controller/Handler or something like that.

Example for a simple registration:

// we talk about the big picture here, not about how jsf is built 
// but how your app is built

// model
package com.foo.domain.registration.entity;

@Entity
public class User {
// fields
}

package com.foo.domain.registration.service;

// also model
@Stateless
public class RegistrationService {

@PersistenceContext
EntityManager em;

public void register(User u) {
em.persist(u);
}
}

package com.foo.presentation

// controller
@Named
@ViewScoped
public class RegistrationController {

@Inject
RegistrationService rs;

User current = new User();

public void register() {
rs.register(u);
}

// get set for current user
}

// view
// quite a lot boilerplate omitted
// form omitted which displays all the necessary field of your current user
// via value="#{registrationContoller.current.name}"
<h:commandButton value="submit" type="submit" action="#{registrationController.register}" />

Available JSF MVC components

I think your understanding is correct.

I'd say that JSF fills most of the part of the controller. There are other libraries that are compatible with JSF though. For example, you can use Spring WebFlow together with JSF to get more powerful navigation features.

JSF is not very intrusive when it comes to the model. Ideally, there aren't any traces that you are using JSF in your domain model (the exception is that JSF provides annotations that you can optionally use, such as @ManagedBean). This means you are free to use any libraries you want. You can use Spring IOC or EJB if you want to, or you can code your entire model in plain old java objects.

That being said, I should like to emphasize that JSP is not obsolete. As digitaljoel points out, Facelets have replaced JSP as the view technology in JSF, but JSP is still alive and healthy in other frameworks. There is not an agreement that JSF including Facelets are "better" than JSP (together with another web framework); and JSF has not become an industry standard.

Writing a web application using JSF is closer to writing a desktop application, since they have abstracted away much of the request-response handling. There is not a specific method being invoked each time a client does a request, instead each request passes through a lifecycle of which you are not fully in control. Interacting directly with the HttpServletRequest is discouraged.

Ignoring the request-response nature of the web increases the complexity of a request and conflicts with another growing trend: rich web applications that heavily relies on Javascript. The responsibility of the view logic is moved from the server to the browser, which interacts with the server using Ajax against thin HTTP APIs.

The point is that JSF is not the end-all framework that you need to learn and ignore everything else. It can be the correct choice for some applications, but not for all.

Why is JSF considered MVP but not MVVM framework

MVVM is mainly a desktop application oriented pattern. When considering MVVM in web application perspective, there would be a controller in the client side. JSF doesn't have such one. When still speaking about web applications, if you were using e.g. Spring MVC in server side with e.g. AngularJS or Node.js in client side, you may speak about MVVM.



Related Topics



Leave a reply



Submit