I have some questions about Bean Validation and JSF validation, currently I am using Bean validation:
With the JSF validation, the validation works client side only, no request sent to server, and Bean validation works on server?
If javascript is disabled are both will work JSF & Bean Validation, or only bean validation?
What are the disadvantages of Bean validation if there are any?
That is not true. The validations are applied during the jsf life cycle by Process Validations.
"Conversion and validation occurs when the JSF runtime calls the
processValidators() method on each component in the view hierarchy.
The processValidators() method will first initiate any data conversion
that is required before validating the components value against the
application’s validation rules. If there are any errors during the
conversion or validation process the component is marked invalid and
an error message is generated and queued in the FacesContext object.
If a component is marked invalid, JSF advances directly to the render
response phase, which will display the current view with the queued
validation error messages. If there are no validation errors, JSF
advances to the update model values phase." - johnderinger.wordpress.com
You can also find this information in the specification.
Both work without javascript.
This is more a question of programming style. I think validation is better made in the model than in the view, because it removes logic from the view and it is more DRY (don't repeat yourself). If you use a bean multiple time, you will have to write the validation only once with bean validation. You should also know that bean validation overwrite constraints in JSF.
More information how to use bean validation, you can find here and the specification here.
For more information about the integrated JSF validation, you should visit this site.
Related
I recently read this article from Neil Griffin Making Distinctions Between Different Kinds of JSF Managed-Beans and it got me thinking about the distinction between different beans in my own application. To quickly summarise the gist:
Model Managed-Bean: This type of managed-bean participates in the
"Model" concern of the MVC design pattern. When you see the word
"model" -- think DATA. A JSF model-bean should be a POJO that follows
the JavaBean design pattern with getters/setters encapsulating
properties.
Backing Managed-Bean: This type of managed-bean participates in the
"View" concern of the MVC design pattern. The purpose of a
backing-bean is to support UI logic, and has a 1::1 relationship with
a JSF view, or a JSF form in a Facelet composition. Although it
typically has JavaBean-style properties with associated
getters/setters, these are properties of the View -- not of the
underlying application data model. JSF backing-beans may also have JSF
actionListener and valueChangeListener methods.
Controller Managed-Bean: This type of managed-bean participates in
the "Controller" concern of the MVC design pattern. The purpose of a
controller bean is to execute some kind of business logic and return a
navigation outcome to the JSF navigation-handler. JSF controller-beans
typically have JSF action methods (and not actionListener methods).
Support Managed-Bean: This type of bean "supports" one or more views
in the "View" concern of the MVC design pattern. The typical use case
is supplying an ArrayList to JSF h:selectOneMenu drop-down
lists that appear in more than one JSF view. If the data in the
dropdown lists is particular to the user, then the bean would be kept
in session scope.
Utility Managed-Bean: This type of bean provides some type of
"utility" function to one or more JSF views. A good example of this
might be a FileUpload bean that can be reused in multiple web
applications.
This made sense to me and for the past few hours I have been refactoring my code and came up with the following with respect to the user login:
The AuthenticationController is an example of a Controller Managed-Bean. It is request-scoped and features two getters and setters for setting a username and password, and two navigation methods, authenticate and logout, navigating the user to either their private area upon successful login, or back to the main page when logging out.
The UserBean is an example of a Support Managed-Bean. It is session-scoped and features an instance of User class (which would be null when you are not authenticated) with a getter and setter, nothing more.
The AuthenticationController has this user as a managed property (#ManagedProperty(value = "#{userController.user} private User user;). Upon successful authentication, the AuthenticationController would set the managed property to the actual user instance with the corresponding username that was used for the login.
Any new beans would be able to grab the user as a managed property as well and pull the data they need, such as group membership for instance, if the User class would feature a list with group names.
Would this way be the proper way to go about with regard to the seperation of concerns?
This is a very subjective question. I personally disagree that article and find that it's giving really bad advice to starters.
Model Managed-Bean: This type of managed-bean participates in the "Model" concern of the MVC design pattern. When you see the word "model" -- think DATA. A JSF model-bean should be a POJO that follows the JavaBean design pattern with getters/setters encapsulating properties.
I would absolutely not make or call it a managed bean. Just make it a property of a #ManagedBean. For example a DTO or JPA #Entity.
Backing Managed-Bean: This type of managed-bean participates in the "View" concern of the MVC design pattern. The purpose of a backing-bean is to support UI logic, and has a 1::1 relationship with a JSF view, or a JSF form in a Facelet composition. Although it typically has JavaBean-style properties with associated getters/setters, these are properties of the View -- not of the underlying application data model. JSF backing-beans may also have JSF actionListener and valueChangeListener methods.
This way you keep duplicating and mapping the properties of the entity in the managed bean. This makes no sense to me. As said, just make the entity a property of the managed bean and let the input fields refer it directly like #{authenticator.user.name} instead of #{authenticator.username}.
Controller Managed-Bean: This type of managed-bean participates in the "Controller" concern of the MVC design pattern. The purpose of a controller bean is to execute some kind of business logic and return a navigation outcome to the JSF navigation-handler. JSF controller-beans typically have JSF action methods (and not actionListener methods).
This describes the #RequestScoped/#ViewScoped #ManagedBean class pretty much. Whether event listener methods are allowed or not depends on whether they are specific to the view which is tied to the bean and/or are for their job dependent on the bean's state. If they are, then they belongs in the bean. If not, then they should be a standalone implementation of any FacesListener interface, but definitely not a managed bean.
Support Managed-Bean: This type of bean "supports" one or more views in the "View" concern of the MVC design pattern. The typical use case is supplying an ArrayList to JSF h:selectOneMenu drop-down lists that appear in more than one JSF view. If the data in the dropdown lists is particular to the user, then the bean would be kept in session scope.
Fine. For application wide data like dropdown lists just use an #ApplicationScoped bean and for session wide data like logged-in user and its preferences just use a #SessionScoped one.
Utility Managed-Bean: This type of bean provides some type of "utility" function to one or more JSF views. A good example of this might be a FileUpload bean that can be reused in multiple web applications.
This makes not really sense to me. Backing beans are usually tied to single views. This sounds too much like an ActionListener implementation which is to be used by <f:actionListener> in command components to your choice. Definitely not a managed bean.
For kickoff examples of the right approach, see also:
Hello World example in Our JSF wiki page
"Bookstore CRUD" example in this answer
"Master-detail" example in this answer
JSF Service Layer
Communication in JSF 2
Does anyone have a solution for such a problem:
In my app I'm using a complex, programmatically build dashboard based on the primefaces dashboard. To overcome problems with nonunique id's of the panels building the dashboard, I'm binding this component to a request-scoped bean. I'd also like to rebuild the dashboard based on some changable parameters after clicking a commandButton.
The problem is, that the getter for the dashboard is fired in the Apply Request Values phase, way before the actionListener of the commandButton is fired (in the Invoke Application phase). So, although the dashboard is rebuild eventually, it's not beeing refreshed in the rendered response.
On the other hand, if I try to set immediate attribute of the button to true, the actionListener is fired in the Apply Request Values phase, but still after the getter. Than the lifecycle goes directly to the Render Response phase, and the outcome is the same.
Anyone?
Thank you for the answer. Let me add a bit detail to my problem.
I store a model of a sports tournament as a property of a session scoped bean. It goes like this: the bean has a property "tournament". This class has a list of groups, each with it's table of matches. The idea was to use three different programmatically built components as renderers of this tournament model.
The dashboard would be used for drag-and-drop edition of contestant placement in groups. For viewing match tables and editing their matches I use a tab panel, with panel grid for every table. Finally, I use a panel grid to show a tournament tree. Every of those three components render some part of the model for the user to edit.
Since the model (and therefore those rendering components) are dynamically build depanding on chosable parameters like number of groups for example, i had a problem with id uniqnes when binding them to a session-scoped bean. So I bound them to a request scoped bean. With every request changing the model (mostly ajax) I wanted to rerender those components depending on the parameters set by the user (also stored in the session scoped bean).
The problem is, that when I rebuild the model in the invoke application phase (in a action listener fired by the "rebuild-my-model" button), the components bound to a request-scoped bean have already been "get-ed" from the bean (or so it seems), and they do not refresh on the page.
I would be very gratefull for a clue to what i'm doing wrong, and perhaps a suggestion, if the approach mentioned above is completelly stupid :)
The problem is, that the getter for the dashboard is fired in the Apply Request Values phase, way before the actionListener of the commandButton is fired
I'm not sure why exactly that forms a problem for you. Perhaps you're incorrectly doing business logic in the getter method instead of in the action listener method? Or perhaps you're manually creating the component instead of referencing the JSF-created one and thus always overridding the one in the JSF view?
A proper JSF getter method basically look like this:
public UIComponent getDashboard() {
return dashboard;
}
It should not contain any other line of code. The same applies to the setter method by the way. Any actions wherein you need to manipulate the component's children needs to be done in an action(listener) method, not in a getter/setter method.
I am trying to implement an audit trail functionality for my web application that records:
lastModified (timestamp)
modifiedBy (user information)
userComment (reason for value change)
for each of my input fields (input fields are spread over several forms with different backing beans and different valueHolder classes).
The first two (lastModified and modifiedBy) are easily done with the help of an JPA AuditListener and #PrePersit and #PreUpdate methods.
The third one is a bit tricky since it requires user interaction. Best would be a dialog that asks for the user comment.
So there are (at least) two open issues: Can I establish a "global" valueChangeListener for all input fields in my application? Is this possible without attaching <f:valueChangeListener> to each single input component? Second: How can I grab the user comment. My idea is to put a p:dialog in my web page template but this dialog needs to know from which input component it is called.
Can I establish a "global" valueChangeListener for all input fields in my application? Is this possible without attaching to each single input component?
Yes, with a SystemEventListener which get executed during PreRenderViewEvent. You need to walk through the component tree as obtained by FacesContext#getViewRoot() to find all components which are an instanceofEditableValueHolder (or something more finer-grained) and then add the new YourValueChangeListener() by the addValueChangeListener() method. See also this answer how to register the system event listener: How to apply a JSF2 phaselistener after viewroot gets built?
Second: How can I grab the user comment. My idea is to put a p:dialog in my web page template but this dialog needs to know from which input component it is called.
You could in YourValueChangeListener#processValueChange() set the component in question as a property of some request or view scoped which you grab by evaluateExpressionGet().
Recorder recorder = (Recorder) context.getApplication().evaluateExpressionGet(context, "#{recorder}", Recorder.class);
recorder.setComponent(event.getComponent());
// ...
It will execute the EL and auto-create the bean in its scope if necessary. The bean in turn should also hold the property representing the user comment. Finally, you can use it in your <p:dialog>.
<p>You have edited #{recorder.component.label}, please mention the reason:</p>
...
<h:inputText value="#{recorder.comment}" />
I guess I knew the difference, but right now I find myself confused. :P
Both of them seem to be do the same thing, except that partialSubmit is used on submit buttons to submit the form using AJAX and autoSubmit is used on editable components, which submits only its own contents. Am I right in saying this?
The accepted answer isn't 100% correct for ADF. The partialTriggers attribute is involved in the lifecycle.
From Enabling Partial Page Rendering Declaratively
The autoSubmit attribute on an input component and the partialSubmit
attribute on a command component are not the same thing. When
partialSubmit is set to true, then only the components that have
values for their partialTriggers attribute will be processed through
the lifecycle. The autoSubmit attribute is used by input and select
components to tell the framework to automatically do a form submit
whenever the value changes. However, when a form is submitted and the
autoSubmit attribute is set to true, a valueChangeEvent event is
invoked, and the lifecycle runs only on the components marked as root
components for that event, and their children. For more information,
see Section 4.4, "Using the Optimized Lifecycle".
They are both AJAX enabled calls occurring from custom properties of custom JSF components. The autoSubmit essentially asynchronously postsback content specific to the component for keeping the server side managed bean values current with the content within the component on the client side.
A partialSubmit is another asynchronous AJAX call that will serve to immediately postback a component value on some kind of component event, like losing focus on an ICEFaces inputText component for example.
The interesting thing to note is that the entire ViewState is posted back on each type of asynchronous submit, so if the values of other components HAD changed on the page before the submit, the bound server side managed bean properties will have their values refreshed as well, even though the client side components MAY not be refreshed to reflect any server side data changes that may have occurred.
In fact, the entire JSF server side lifecycle occurs on each postback, read the following article on implementing a debug PhaseListener that allows you to see what Phases are occurring after each asynchronous submit operation occurs.
http://balusc.blogspot.com/2006/09/debug-jsf-lifecycle.html
The scenario is the following:
A managed bean uses as attributes another managed bean, like customerBean.current.customerAgreement. When I display the data on a pge the expression #{customerBean.current.customerAgreement.agreementTitle} is filled and shows the expected output.
However in an inputText the value is only changed on the screen, not in the value I get back in the managedBean. Is there a limitation on how deep such a structure can be constructed?
No, there is basically no limitation in how deep you can nest beans.
Your problem is caused by something else. Perhaps you are not preserving the same parent beans in the request of the form submit as it was during the request of the form display. Hard to tell without further detail about your code. All what I can suggest is to try making CustomerBean a view scoped bean.