Running your first JSF 2.3 code
JavaServer Faces (JSF) is the Java technology made to simplify the process of building a UIs, despite how it's made for the frontend and the UI is built in the backend.
With JSF, you can build components and use (or reuse) them in the UI in an extensible way. You can also use other powerful APIs, such as CDI and Bean Validation, to improve your application and its architecture.
In this recipe, we will use the Validator
and Converter
interfaces with the new feature introduced by version 2.3, which is the possibility of using them with generic parameters.
Getting ready
First, we need to add the dependencies needed:
<dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>8.0</version> <scope>provided</scope> </dependency>
How to do it...
- Let's create a
User
class as the main object of our recipe:
public class User implements Serializable { private String name; private String email; public User(String name, String email) { this.name = name; this.email = email; } //DON'T FORGET THE GETTERS AND SETTERS //THIS RECIPE WON'T WORK WITHOUT THEM }
- Now, we create a
UserBean
class to manage our UI:
@Named @ViewScoped public class UserBean implements Serializable { private User user; public UserBean(){ user = new User("Elder Moraes", "[email protected]"); } public void userAction(){ FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Name|Password welformed")); } //DON'T FORGET THE GETTERS AND SETTERS //THIS RECIPE WON'T WORK WITHOUT THEM }
- Now, we implement the
Converter
interface with aUser
parameter:
@FacesConverter("userConverter") public class UserConverter implements Converter<User> { @Override public String getAsString(FacesContext fc, UIComponent uic, User user) { return user.getName() + "|" + user.getEmail(); } @Override public User getAsObject(FacesContext fc, UIComponent uic, String string) { return new User(string.substring(0, string.indexOf("|")), string.substring(string.indexOf("|") + 1)); } }
- Now, we implement the
Validator
interface with aUser
parameter:
@FacesValidator("userValidator") public class UserValidator implements Validator<User> { @Override public void validate(FacesContext fc, UIComponent uic, User user) throws ValidatorException { if(!user.getEmail().contains("@")){ throw new ValidatorException(new FacesMessage(null, "Malformed e-mail")); } } }
- And then we create our UI using all of them:
<h:body> <h:form> <h:panelGrid columns="3"> <h:outputLabel value="Name|E-mail:" for="userNameEmail"/> <h:inputText id="userNameEmail" value="#{userBean.user}" converter="userConverter" validator="userValidator"/> <h:message for="userNameEmail"/> </h:panelGrid> <h:commandButton value="Validate" action="#{userBean.userAction()}"/> </h:form> </h:body>
Don't forget to run it in a Java EE 8 server.
How it works...
The UserBean
class manages the communication between the UI and the server. Once you instantiate the user
object, it is available for both of them.
That's why when you run it, the Name | E-mail
is already filled (the user
object is instantiated when the UserBean
class is created by the server).
We associated the userAction()
method from the UserBean
class to the Validate
button of the UI:
<h:commandButton value="Validate" action="#{userBean.userAction()}"/>
You can create other methods in UserBean
and do the same to empower your application.
The whole core of our recipe is represented by just a single line in the UI:
<h:inputText id="userNameEmail" value="#{userBean.user}" converter="userConverter" validator="userValidator"/>
So, our two implemented interfaces used here are userConverter
and userValidator
.
Basically, the UserConverter
class (with getAsString
and getAsObject
methods) converts an object to/from a string and vice versa, according to the logic defined by you.
We have just mentioned it in the preceding code snippet:
value="#{userBean.user}"
The server uses the userConverter
object, calls the getAsString
method, and prints the result using the preceding expression language.
Finally, the UserValidator
class is automatically called when you submit the form, by calling its validate
method, and applying the rules defined by you.
There's more...
You could increase the validators by adding a Bean Validation on it and, for example, defining the email
property from User
with an @Email
constraint.
See also
- You can stay tuned with everything related to JSF at https://javaserverfaces.github.io/
- The source code of this recipe is at https://github.com/eldermoraes/javaee8-cookbook/tree/master/chapter01/ch01-jsf