This question already has answers here:
What components are MVC in JSF MVC framework?
(4 answers)
JSF Controller, Service and DAO
(2 answers)
Closed 5 years ago.
Good day
I am creating my first JSF based application. I am using:
Wildfly 11
PostgreSQL
Maven based project
IntelliJ Ultimate 2017.3
CentOS 7.4
Apache Shiro
Primefaces 6.1
The model portion of the application is the easy part as it is entities generated from the database using IntelliJ Ultimate's auto schema generation.
I am very confident using JPA and the #PersistanceContext to create an entity manager and use JPSQL.
The xhtml files using JSF tags and the EL language creates the front end and together with a #ViewScoped backing bean forms the view.
Where I am confused about is what should the controller portion consists of?
A problem I seem to frequently run into is getting null pointer exceptions and other errors related to backing bean methods when variables used in these methods have not been properly initialized, especially lists that have to be retrieved from the database using JPA where parameters used in the em queries still needs to be set in the form (but the forms fail to display due to uninitialized variables).
So, I have a questions, and would really appreciate enlightenment.
How do I prevent these null pointer exceptions?
If all the DB 'stuff' is moved to 'controller' beans, and the view backing beans only call the methods in the controller beans, will this eliminate my null pointer exceptions?
What must (according to best practices) a view backing bean contain?
What must (according to best practices) a controller bean contain and be responsible for?
Any advice would be most appreciated.
Related
I am trying to understand the life-cycle of JSF and I was reading through the following tutorial:
JSF tutorial
it says :
The view contains all the GUI components and there is a great deal of
state management by JSF to track the status of the view – typically
using HTML hidden fields.
I am confused that whether JSF Application keep that Managed bean's state during its interaction with the client is interacting, or it uses HTML hidden fields for the same, and mock a stateful bean.
The term "JSF state" does not concern managed bean properties (the model values). It concerns the UI component properties, such as required, valid, immediate, disabled, readonly, rendered, etc. This is basically referenced by only one hidden input field and not multiple fields as that tutorial seems to imply. That hidden input field is the one with javax.faces.ViewState prefix in the name.
Technically, JSF managed beans are always stateful. Statefulness is expressed by whether or not having mutable instance variables. Javabeans are basically always mutable and thus stateful. JSF managed bean state is however not stored in the "JSF state". JSF managed beans are just stored in server's memory, usually as an attribute of the HTTP request, session or application.
See also:
Why JSF saves the state of UI components on server?
Unrelated to the concrete problem, the tutorial you're reading is a JSF 1.x targeted one. JSF 2.x was introduced 5 years ago already. In case of developer tutorials, always pay attention to the publish date and also what version it treats. You can get started at our JSF wiki page.
I'm in the process of migrating from jsf1.1 to jsf2.0. When testing one of the jsf page that I've converted, it encountered the java.io.NotSerializableException on one of the class. I'm not getting this error when it was under jsf1.1. To resolve the problem, I added the Serializable interface to the class. After I did that I get the same error on a different class. I know I can simply add Serializable interface to this class to resolve the issue. But is this normal when migrating from jsf1.1 to jsf 2.0?
You're only getting this error now because in JSF 1.x, partial state saving wasn't a requirement. For a primer on JSF state saving, See this question.
From the JSF 2.x Spec:
For Applications versioned at 1.2 and under, the runtime must not use the partial state saving mechanism. For applications versioned at 2.0 and above, the runtime must use the partial state saving mechanism
This stipulation is what forces any and all view components to be serializable
Technically, anything stored in the session should be serializeable. In JSF, the view and flash scopes are stored within the session. So in short anything not in the request scope will end up in the session. However, you don't see the error until things are serialized out of the session. I don't know the details, but there msut be a difference in JSF 1.1 and JSF 2.0 implementations were JSF 2.0 is more aggressive at serializing the session.
I have a few questions on the various options and best practices when using JSF with EJB3.1. The mental model I have, given the daunting amount of choices and combinations available, is far from clear so some questions may not make sense.
JSF/Facelets reference backing beans (I am using the term "backing bean" for beans whose properties are written or read from Facelets pages) through EL code that is agnostic as to the actual annotations used in the bean classes (javax.faces.bean.* or javax.enterprise.context.*).
Is it correct to say that one can toggle between JSF and CDI scope annotations just by changing the imports in the bean classes without any changes to the Facelets xhtml code?
Is it an established pattern that JSF/Facelets should be used only for the xhtml markup code with all scope and lifecycle (plus injection) annotations done using CDI?
In a JBoss AS setting, where is the lifecycle management of the JSF backing beans (using either JSF or CDI annotations) taking place? In the web container or in the EJB3 container?
In a typical web application given that the SessionScoped beans can be provided by CDI, is there any need for using EJB3 beans other than those of type #Entity, e.g. for the last typical step in each "flow" when information is to be persisted in the database?
Is it correct to say that one can toggle between JSF and CDI scope annotations just by changing the imports in the bean classes without any changes to the Facelets xhtml code?
Yes.
Is it an established pattern that JSF/Facelets should be used only for the xhtml markup code with all scope and lifecycle (plus injection) annotations done using CDI?
JSF is moving towards CDI. The new #FlowScoped annotation of the upcoming JSF 2.2 is evidence of this as this extends from the CDI API. The only disadvantage is that CDI doesn't offer a standard annotation for the tremendously useful JSF #ViewScoped annotation. You'd need #ConversationScoped wherein you manually start and end the conversation, or take a look at a CDI extension like MyFaces CODI.
In a JBoss AS setting, where is the lifecycle management of the JSF backing beans (using either JSF or CDI annotations) taking place? In the web container or in the EJB3 container?
The web container (in flavor of a WAR). JSF is built on top of the Servlet API, so it's definitely the web container.
In a typical web application given that the SessionScoped beans can be provided by CDI, is there any need for using EJB3 beans other than those of type #Entity, e.g. for the last typical step in each "flow" when information is to be persisted in the database?
The #Entity is part of JPA, not of EJB. The #Entity is to be used on a model class which is mapped to a database table and usually solely meant to transfer data across the layers. What you're last describing sounds like candidate for a #Stateful EJB. To understand #Stateless vs #Stateful EJBs better, head to this detailed answer: JSF request scoped bean keeps recreating new Stateful session beans on every request?
I have a jsf 1.2 application where I need to show a page (jsp) which has a backing bean. Most examples I see for help show a blank jsp for user ot edit. In my case I need to get some Data from DB before jsp loads, how to accomplish this?
I tried #postconstruct on a backing bean method but if I share this bean with multiple JSPs it is initializing the info for all pages, I need different data for different page and each page should read some data from db before displaying in JSP.
I am coming from Struts background where I would invoke the URL for the Action which will call have Business logic to get data and then I would direct to JSP. For accomplishign this with JSF it seems not pretty straightforward.
I tried #postconstruct on a backing bean method but if I share this bean with multiple JSPs it is initializing the info for all pages, I need different data for different page and each page should read some data from db before displaying in JSP.
The page (view) should have its own request/view scoped backing bean which is not shared elsewhere. That should fix your "problem" (which is actually just a design matter). Do not use a single session scoped bean for multiple views. That's wrong use of the session scope.
I am coming from Struts background where I would invoke the URL for the Action which will call have Business logic to get data and then I would direct to JSP. For accomplishign this with JSF it seems not pretty straightforward.
JSF and Struts are very different. JSF is a component based MVC framework while Struts is an action based MVC framework. You should not design JSF backing bean classes while having Struts action classes in mind. Going through some decent JSF tutorials should put you on the right track. For an overview, see also the bottom of our JSF wiki page.
Please note that JSF 1.2 is completely outdated. JSF 2.0 has been released over 2 years ago already. If this is a new application or just hobbying, I recommend to forget JSF 1.2 and continue with JSF 2.0.
I was wondering which scope to use for a CRUD Application. Using #ReqeustScoped causes an access to the database for every request. With #SessionScoped, data can be cached in the managed bean, but can cause the so called session-bloat. Moreover, it is more difficult to keep the data up to date. What would you recommend? Is there a best-practice solution.
Thanks,
Theo
Right, you want the scope there in between: #ViewScoped. This scope lives as long as you're submitting and navigating to the same view.
See also:
JSF 2.0 new features, View Scope
CRUD in JSF 2.0 (with code example)