Category Archives: Web App [english]

JSF Mini Book – Tips, concepts and good practices

Hello, how are you?

This post was written as an article to a Brazilian Java magazine. Unfortunately it was not published =(. I decided to post it here! =D

This post will display tips, concepts and solutions to developers that works with JSF 2.0 every day. We will see the concepts and the right way of using the JSF to help those who works with this technology or has interest in learning it – students or developers that works with others frameworks. Using this tool without knowledge of it will give more problems to your software instead solutions. It is really needed to understand how the JSF works, how it handles each user action request and how it is possible to build a software code that will optimize the JSF usage.

We will see some technical questions like: importing images/javascript into the pages, how to upgrade a JSF 1.2 app to a JSF 2.0, using Ajax that is a technology of asynchronously requests, and more; we will see some needed theory that is usually set aside.

With JSF we will be able to face one of the major problems of the web technology, code reuse. The JSF allow us to reuse the code of pages, javascript and validations in Java code that are used in the pages. When we reuse the code we will reduce the maintenance time expend, the change impacts will reduce also and others.

Today we will see:

  • Page 02: Creating a JSF project
  • Page 03: How to import CSS/Images/JavaScript as Library
  • Page 04: XHTML page reuse with Facelets
  • Page 05: JSP x Facelets
  • Page 06: Hiding the comments of the xhtml page
  • Page 07: Avoiding @SessionScoped type. Check all Scope Types
  • Page 08: Avoiding the use of logic in the xhtml page
  • Page 09: Use the h:outputLink to navigate
  • Page 10: Ajax with JSF 2.0
  • Page 11: Smoothing the JSF development
  • Page 12: Upgrading from JSF 1.2 to 2.0
  • Page 13: How to receive null value from the view
  • Page 14: Choosing between action and actionListener
  • Page 15: Flash Scope
  • Page 16: Dot no mix JSF Implementations
  • Page 17: Internationalization as good practice
  • Page 18: JSF 2.2 new features

This post is a celebration for the mark of 200k of viewers that we received in the two years of existence of this blog.

“The Father of Java” uses Jelastic

Hello, how are you?

Today we will have an unusual post, it is more like a good news about this framework that is getting its space in the development world. Jelastic has as characteristic to work as a container of containers.

This news were sent to me by Judah Johns from Jelastic.

As far as we can tell, this is the first PaaS that Dr. Gosling has given his endorsement. We reached out to him to confirm it, and sure enough, it turns out that he is a very happy Jelastic user and is very excited about what he can do with it and what he will be doing with it in the near future.

Though I know that in our community, most everyone knows who James Gosling is, there a lot of younger guys learning Java that have never heard of him, like my 13 year-old brother, Daniel, who is quite an avid Java coder. So, who is James Gosling?

The Dr. James Gosling Bio

This bio comes from Gosling’s own blog: James Gosling received a BSc in Computer Science from the University of Calgary, Canada in 1977. He received a PhD in Computer Science from Carnegie-Mellon University in 1983. The title of his thesis was “The Algebraic Manipulation of Constraints”. He spent many years as a VP & Fellow at Sun Microsystems. He has built satellite data acquisition systems, a multiprocessor version of Unix, several compilers, mail systems and window managers. He has also built a WYSIWYG text editor, a constraint based drawing editor and a text editor called `Emacs’ for Unix systems.

At Sun his early activity was as lead engineer of the NeWS window system. He did the original design of the Java programming language and implemented its original compiler and virtual machine. He has been a contributor to the Real-Time Specification for Java, and a researcher at Sun labs where his primary interest was software development tools. He then was the Chief Technology Officer of Sun’s Developer Products Group and the CTO of Sun’s Client Software Group. He briefly worked for Oracle after the acquisition of Sun. After a year off, he spent some time at Google and is now the chief software architect at Liquid Robotics where he spends his time writing software for the Wave Glider, an autonomous ocean-going robot.

Full Web Application with Tomcat JSF Primefaces JPA Hibernate

Hello, how are you?

We are happy for the 100k visitors. To celebrate this mark in this blog we created this post that will show how to create a full web application using the following tools: Tomcat7, JSF2 (Facelets and Libraries) with Primefaces (with AutoComplete), JPA / Hibernate (with a relationship NxN), Login with Filter.

If you want to see a full web application with JSF + EJB + JPA + JBoss 7 click here.

To run the code of this post you will need the artifacts bellow (all jar file you will find in the last page of this post):

You can use the any database you want, you will need the specific driver of the database and to edit the URL connection at the persistence.xml.

At the end of this post you will find the source code with all needed libraries to download.

What you will see today in this post:

  • Page 02: Entity classes of the model. A relationship NxN (@ManyToMany), NamedQueries with JoinFetch, Enum as attribute.
  • Page 03: Generic DAO, application transaction methods, generic methods to populate query parameters.
  • Page 04: Façades an transactions, using the method findReferenceOnly, care using the entityManager.merge() method.
  • Page 05: Filters.
  • Page 06: ManagedBeans. How to inject a ManagedBean inside another ManagedBean, observations about @ViewScoped.
  • Page 07: JSFMessageUtil.
  • Page 08: Configurations file: log4j.properties, messages.properties.
  • Page 09: xhtml pages, Facelets.
  • Page 10: Primefaces AutoComplete, JSF Converter with “forClass”.
  • Page 11: Easiest way to use CSS/javascript/images with JSF.
  • Page 12: “web.xml” configurations.
  • Page 13: Increasing the security of your application.
  • Page 14: Running the application.

The application that you will find in here will have a Dog and Person CRUD (Create, Read, Update, and Delete); only the ADMIN will have access to the Dog CRUD. Before you run this application you should create a database named “JSFCrudDB”.

Lazy JSF Datatable Pagination (Primefaces)

Hello, how are you?

Today we will do JSF datatable pagination with a Lazy List with a view scoped managed bean. What all those words/expressions mean?

There are several JSF frameworks today that provide datatables with a ready pagination, columns sorter and others functionalities. Today we will use the Primefaces datatable.

Usually the datatables will put the displayed List, with the entities, inside the user http session. Increasing the objects inside the user session will have a direct impact on the server performance; each user that displays a datatable,  that keeps a list in the session, will be allocating more and more memory in the server.

To look like real life, our post will use JPA and HSQLDB as database, and we will use JPQL to query the data.

In the end of this post you will find the link to download the source code.

We will use:

  • JSF 2.0 – JBoss 7 Implementation
  • JBoss 7.1 – the code of this post should be applied to all servers
  • Eclipse Indigo
  • JPA 2.0 – JBoss 7 Implementation
  • HSQLDB (2.2.8) – The HSQL it is a memory database, it will be easier to run it.
  • Primefaces 3.2

This post is not about good development practices nor about adding classes layers of project modeling. I just intend to show how to do a pagination without a session managed bean.

Full WebApplication JSF EJB JPA JAAS

Hello, how are you?

This post will be the biggest so far in my blog! We will see a full web application. It will be done will the newest technologies (until today), but I will give some hints to show how to adapt this post to older technologies.

In the end of this post you will find the source code to download. You can use it as you wish. Just go to the last page and do the download. \o/

If you downloaded the code and did not understand something, in this post I will explain every detail found in the code. Just read the subject inside this post that you want.

I will list bellow the technologies that I will use in this post:

  • JSF 2.0 Mojarra – With ManagedBeans as RequestScope and SessionScope.
  • Message Internationalization – File that will have all the messages of our system; it will be easier to translate you pages.
  • Default CSS file that will be imported as a library.
  • EJB 3 – Our DAOs and Façades will be @Stateless.
  • Generic DAO – A generic DAO that will have the CRUD actions to make our life easier.
  • JPA 2 – To map our classes in the DB
  • JAAS – To control the login and the user access to the pages.
  • MVC – I will use this pattern with small modifications.
  • Postgres as database, but I will show how to set up your app to MySQL also.

I will not use TDD – JUnit to test our View/Model/Classes, but in the following link you can see a technique to use the JUnit to test your ManagedBeans: JUnit with HSQLDB, JPA and Hibernate.

Tools that we will use:

This post will have several pages; this first page is just to show the technical details of the post today.

I will not code to interface my model/DAO, just to save space. Remember that you should always code to interfaces (Design Pattern – Strategy).

Before you go to the next pages be sure that you installed the JBoss Tools and the JBoss 7 in this exactly order.

JSF RESTFull Get Request Parameters

Hello, how are you?

How can we pass parameters through a URL using JSF 2.0? I believe this will be smallest post here.

At the end of this post you will find the link to download the created source code.

The other posts about JSF/Web Applications you can find in here: JSF Simple Ajax SamplesJSF Persisting Objects and Messages after a Redirect ,User Login Validation with JAAS and JSFJSF: Converter and Bean AutoCompleteJSF – Hello World, Auto CompleteHandling Exceptions on a WebAppUser Authentication (Filter/Servlet)Creating a WebServer.

Take a look bellow to see that is very easy to receive a parameter through a URL:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core">
<h:head>
	<f:metadata>
		<f:viewParam name="email" value="#{user.email}" />
		<f:viewParam name="name" value="#{user.name}" />
	</f:metadata>
</h:head>
<h:body>
	<h:form>
		Your email is: #{user.email} <br/>
		Your name is: #{user.name} <br/>
		Your name and email from MB: #{user.nameAndEmail} <br/>
	</h:form>
</h:body>
</html>
package demo;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

/**
 * Created by JBoss Tools
 */
@ManagedBean(name = "user")
@RequestScoped
public class User {

	private String email;
	private String name;

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getNameAndEmail(){
		return email + " " + name;
	}
}

The used URL to access that page is: http://localhost:8080/RequestParameter/values.xhtml?email=Read+Romans&name=Chapter10+Ver+09.

As you can see the page expects two parameters and in our ManagedBean exists a method that uses both parameters; in this method you could search for your entities in the database or any other action that you need.

How can we create a link to be navigated by the user? Piece of cake, take a look at the page/code bellow:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core">
<h:head>

</h:head>
<h:body>
	<h:form>
		01) A pre-formed link: <br/>
		<h:link outcome="values?email=Read Romans&amp;name=Chapter10 Ver 09" value="Let us go!" />
		<br/>
		<br/>
		02)Link with the f:param component<br/>
		<h:link outcome="values" value="Write all params and let us go!" >
			<f:param name="email" value="Read Romans" />
			<f:param name="name" value="Chapter10 Ver 09" />
		</h:link>
		<br/>
		<br/>
		03) <h:commandLink value="Redirect Me!" action="values?faces-redirect=true&amp;email=Read Romans&amp;name=Chapter10 Ver 09" />
	</h:form>
</h:body>
</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core">
<h:head>
	<f:metadata>
		<f:viewParam name="email" value="#{user.email}" />
		<f:viewParam name="name" value="#{user.name}" />
	</f:metadata>
</h:head>
<h:body>
	<h:form>
		Your email is: #{user.email} <br/>
		Your name is: #{user.name} <br/>
		Your name and email from MB: #{user.nameAndEmail} <br/>

		04) <h:link outcome="values" value="Get everybody and leave this place" includeViewParams="true" />
	</h:form>
</h:body>
</html>


I will talk about each approach used in the codes to generate the links (according to each number used like 01, 02…):

  • 01)  A pre-formed link that has all the parameters written in it.
  • 02)  We are using the “f:param” component that gives us a cleaner code.
  • 03)  A link that will use the redirect to navigate through the commandLink component. BE CAREFULL: until today, the JSF will not send paramters in a redirect if you use the “f:param” component. That is why I wrote all URL in the link with the redirect. “<h:commandLink action=”values?faces-redirect=true”.
  • 04)  Using this approach with the option (includeViewParams=”true”) you will automatically includ all the “f:viewParam” that are present in the view. You will not need to write them in the “h:link” component. JSF will gather all the parameters for you.

You can also add parameters when you use the navigation through the “faces-config.xml”:

<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
	<navigation-rule>
		<navigation-case>
			<from-outcome>redirectMe</from-outcome>
			<to-view-id>/myPage.xhtml</to-view-id>
			<redirect include-view-params="true">
				<view-param>
					<name>calculatedValue</name>
					<value>#{myBean.value}</value>
				</view-param>
			</redirect>
		</navigation-case>
	</navigation-rule>
</faces-config>

The code from this post will work with the “h:link” or the “h:commandLink” and both can be used with the redirect option.

I also want to remind you that your URL can be wrote in a ManagedBean and the value used like #{youMB.createTheURL} in the “link/commandLink” components.

Click here to download the source code.

I hope this post helps you.

If you have any question/doubt/suggestion just post it.

See you soon. \o_

JSF Simple Ajax Samples

Hello, how are you?

Today we will see some Simple Samples of Ajax with JSF.

If you want to see other posts about JSF/Web Applications click on the next links: JSF Persisting Objects and Messages after a Redirect ,User Login Validation with JAAS and JSFJSF: Converter and Bean AutoComplete, JSF – Hello World, Auto Complete, Handling Exceptions on a WebApp, User Authentication (Filter/Servlet), Creating a WebServer.

In the end of this post you will find the link to download the source code of the samples. In this post (User Login Validation with JAAS and JSF) I show how to install the JBoss 6 in case you want to run the project from today. You will need to install the JBoss tools plugin in your Eclipse.

Take a look at the page bellow and its code:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core">
<h:head>
</h:head>
<h:body>
	<h:form>
		Your Name: <h:inputText id="inputname" label="${msgs.prompt}" value="#{user.name}"/>
		<br />
		<h:commandButton action="#{user.sayHello}" value="Display my name here, now!"/>
		<br />
	</h:form>
</h:body>
</html>

How could we display the typed name in the same screen using Ajax? Piece of cake, just add the “f:ajax” component. Check the code update and the result:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core">
<h:head>
</h:head>
<h:body>
	<h:form>
		Your Name: <h:inputText id="inputname" label="${msgs.prompt}" value="#{user.name}"/>
		<br />
		<h:commandButton action="#{user.sayHello}" value="Display my name here, now!">
			<f:ajax render="myName" execute="inputname" />
		</h:commandButton>
		<br />
		<br />
		<h:outputText id="myName" value="#{user.name}" />
	</h:form>
</h:body>
</html>

It is very easy right? We just need to pass the value that will be carried to the ManagedBean by the “execute” parameter; with the “render” parameter we will tell to the JSF which component will be “refreshed”.

Notice also that the typed name appears in the Console.

With this code we can “refresh” all kind of components. Let us see another sample?

Let us display an error message if the user types a name with less than 4 characters.

Check our new message and the new code:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core">
<h:head>
</h:head>
<h:body>
	<h:form>
		<h:messages id="myMessage" globalOnly="true" showDetail="true"/>
		Your Name: <h:inputText id="inputname" label="${msgs.prompt}" value="#{user.name}"/>
		<br />
		<h:commandButton action="#{user.sayHello}" value="Display my name here, now!">
			<f:ajax render="myName myMessage" execute="inputname" />
		</h:commandButton>
		<br />
		<br />
		<h:outputText id="myName" value="#{user.name}" />
	</h:form>
</h:body>
</html>
package demo;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;

/**
 * Created by JBoss Tools
 */
@ManagedBean(name = "user")
@RequestScoped
public class User {

	private String name;

	public String sayHello() {
		if (isNameIncorrect()) {
			FacesContext context = FacesContext.getCurrentInstance();
			context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Too small", "Can you write it a little bigger?"));
		}

		System.out.println(name);
		return null;
	}

	private boolean isNameIncorrect() {
		return "".equals(name.trim()) || name.length() < 3;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

Notice that we have the component “h:messages” and its ID is used in the “f:ajax” component. This code also works when you use the “h:message for=“YYY”” component.

What if we work now with comboboxes? Let us display a combobox that will contain 4 items when we have a name with less than 6 characters, and a list with more than 4 items if the typed name has more than 6 characters.

package demo;

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

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.component.UISelectItems;
import javax.faces.component.html.HtmlSelectOneMenu;
import javax.faces.context.FacesContext;
import javax.faces.event.AjaxBehaviorEvent;

/**
 * Created by JBoss Tools
 */
@ManagedBean(name = "user")
@RequestScoped
public class User {

	private String name;

	private List<String> cars;

	private String selectedCar;
	private HtmlSelectOneMenu htmlSelectCars;

	private static final String SELECT_A_CAR = "Select One Car";

	public User() {
		cars = new ArrayList<String>();
	}

	public String sayHello() {
		if (isNameInCorrect()) {
			FacesContext context = FacesContext.getCurrentInstance();
			context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Too small", "Can you write it a little bigger?"));
		}

		System.out.println(name);
		return null;
	}

	private boolean isNameInCorrect() {
		return name == null || "".equals(name.trim()) || name.length() < 3;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void editMyCarsList(AjaxBehaviorEvent event) {
		if (htmlSelectCars == null) {
			htmlSelectCars = new HtmlSelectOneMenu();
		}

		htmlSelectCars.getChildren().clear();

		UISelectItems items = new UISelectItems();
		items.setValue(getCars());
		htmlSelectCars.getChildren().add(items);
	}

	public List<String> getCars() {
		cars.clear();

		cars.add(SELECT_A_CAR);

		if (!isNameInCorrect() && name.length() >= 6) {
			cars.add("Ferrari");
			cars.add("Porch");
			cars.add("Beetle");
			cars.add("Opala");
			cars.add("Passat");
			cars.add("Vectra");
			cars.add("Chevet");
			cars.add("Corvet");
		} else {
			cars.add("Ferrari");
			cars.add("Porch");
			cars.add("Beetle");
			cars.add("Opala");
		}

		return cars;
	}

	public void setCars(List<String> cars) {
		this.cars = cars;
	}

	public String getSelectedCar() {
		return selectedCar;
	}

	public void setSelectedCar(String selectedCar) {
		this.selectedCar = selectedCar;
	}

	public HtmlSelectOneMenu getHtmlSelectCars() {
		editMyCarsList(null);

		return htmlSelectCars;
	}

	public void setHtmlSelectCars(HtmlSelectOneMenu htmlSelectCars) {
		this.htmlSelectCars = htmlSelectCars;
	}
}

Take a look now at our page:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core">
<h:head>
</h:head>
<h:body>
	<h:form>
		<h:messages id="myMessage" globalOnly="true" showDetail="true" />
		Your Name: <h:inputText id="inputname" label="${msgs.prompt}" value="#{user.name}" />
		<br />
		<h:commandButton action="#{user.sayHello}" value="Display my name here, now!">
			<f:ajax render="myName myCars myMessage" execute="inputname" listener="#{user.editMyCarsList}" />
		</h:commandButton>
		<br />
		<br />
		<h:outputText id="myName" value="#{user.name}" />
		<br />
		<br />
		Choose your car: <h:selectOneMenu id="myCars" binding="#{user.htmlSelectCars}" value="#{user.selectedCar}" />
		<br />
		<br />
	</h:form>
</h:body>
</html>

Notice that our combobox items size is updated according to the typed name. At the end of this post I will talk more about why I used the binding attribute to the HtmlSelectOneMenu instead returning the List<String>.

As our last sample, let us create a combobox that will appear and disappear according to the selected value in the Car combobox.

Take a look at our ManagedBean:

package demo;

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

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.component.UISelectItems;
import javax.faces.component.html.HtmlSelectOneMenu;
import javax.faces.context.FacesContext;
import javax.faces.event.AjaxBehaviorEvent;

/**
 * Created by JBoss Tools
 */
@ManagedBean(name = "user")
@RequestScoped
public class User {

	private String name;

	private List<String> cars;
	private List<String> colors;

	private String selectedCar;
	private String selectedColor;
	private HtmlSelectOneMenu htmlSelectCars;

	private static final String SELECT_A_CAR = "Select One Car";

	public User() {
		cars = new ArrayList<String>();
		colors = new ArrayList<String>();

		colors.add("Red");
		colors.add("Blue");
		colors.add("Orange");
		colors.add("Pink --> O.o");
	}

	public String sayHello() {
		if (isNameInCorrect()) {
			FacesContext context = FacesContext.getCurrentInstance();
			context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Too small", "Can you write it a little bigger?"));
		}

		System.out.println(name);
		return null;
	}

	private boolean isNameInCorrect() {
		return name == null || "".equals(name.trim()) || name.length() < 3;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void editMyCarsList(AjaxBehaviorEvent event) {
		if (htmlSelectCars == null) {
			htmlSelectCars = new HtmlSelectOneMenu();
		}

		htmlSelectCars.getChildren().clear();

		UISelectItems items = new UISelectItems();
		items.setValue(getCars());
		htmlSelectCars.getChildren().add(items);
	}

	public List<String> getCars() {
		cars.clear();

		cars.add(SELECT_A_CAR);

		if (!isNameInCorrect() && name.length() >= 6) {
			cars.add("Ferrari");
			cars.add("Porch");
			cars.add("Beetle");
			cars.add("Opala");
			cars.add("Passat");
			cars.add("Vectra");
			cars.add("Chevet");
			cars.add("Corvet");
		} else {
			cars.add("Ferrari");
			cars.add("Porch");
			cars.add("Beetle");
			cars.add("Opala");
		}

		return cars;
	}

	public void setCars(List<String> cars) {
		this.cars = cars;
	}

	public String getSelectedCar() {
		return selectedCar;
	}

	public void setSelectedCar(String selectedCar) {
		this.selectedCar = selectedCar;
	}

	public List<String> getColors() {
		return colors;
	}

	public void setColors(List<String> colors) {
		this.colors = colors;
	}

	public boolean isColorsAlloweToDisplay() {
		if (isNameInCorrect()) {
			return false;
		}

		if (selectedCar == null || selectedCar.trim().equals("") || selectedCar.equals(SELECT_A_CAR)) {
			return false;
		}

		return true;
	}

	public String getSelectedColor() {
		return selectedColor;
	}

	public void setSelectedColor(String selectedColor) {
		this.selectedColor = selectedColor;
	}

	public HtmlSelectOneMenu getHtmlSelectCars() {
		editMyCarsList(null);

		return htmlSelectCars;
	}

	public void setHtmlSelectCars(HtmlSelectOneMenu htmlSelectCars) {
		this.htmlSelectCars = htmlSelectCars;
	}
}

Our ManagedBean were lightly updated, we just added a List with a method that return a list of colors that will populate our combobox; we added also a method that will return a Boolean – true if the combobox is allowed to be displayed.

Check our new page:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core">
<h:head>
</h:head>
<h:body>
	<h:form>
		<h:messages id="myMessage" globalOnly="true" showDetail="true" />
		Your Name: <h:inputText id="inputname" label="${msgs.prompt}" value="#{user.name}" />
		<br />
		<h:commandButton action="#{user.sayHello}" value="Display my name here, now!">
			<f:ajax render="myName myCars myMessage myColors" execute="inputname" listener="#{user.editMyCarsList}" />
		</h:commandButton>
		<br />
		<br />
		<h:outputText id="myName" value="#{user.name}" />
		<br />
		<br />
		Choose your car:
		<h:selectOneMenu id="myCars" binding="#{user.htmlSelectCars}" value="#{user.selectedCar}">
			<f:ajax render="myColors" execute="inputname myCars"/>
		</h:selectOneMenu>
		<br />
		<br />
		<h:panelGroup id="myColors">
			<h:selectOneMenu value="#{user.selectedColor}" rendered="#{user.colorsAlloweToDisplay}">
				<f:selectItems value="#{user.colors}" />
			</h:selectOneMenu>
		</h:panelGroup>
	</h:form>
	</h:body>
</html>

I will talk about the code used in the post:

  • HtmlSelectOneMenu – I used the component instead a List because the JSF is not so good in render the components in the user screen (DOM Tree). If your combobox has 4 lines and by using ajax you add more lines to the List, the JSF/Ajax will not recognize the new added lines; you will be able to use only the older values. You can try to use the code with a List<String> instead using the HtmlSelectOneMenu and see the result; I spend like 3~4 hours to understand this by a lot of searches on the internet.
  • HtmlSelectOneMenu inside the “h:panelGroup” component – I did this because every time you want to render a non rendered component you need to update its container. If our selectOne were inside the same form of the car selectOne you would need to render all form.

Click here to download the code from this post.

I hope this post might help you.

If you have any question/doubt/suggestion just post it.

See you later. \o_

JSF Persisting Objects and Messages after a Redirect

Hello, how are you?

Let us talk today about how to send messages with JSF after a redirect action. The redirect action will not carry any data from the first request; sometimes you will not have the value to be displayed.

We often see this happen in an application with a heavy use of Ajax; sometimes to navigate between the pages you will need to use the redirect command.

The other posts of JSF/Web you can find in here: User Login Validation with JAAS and JSFJSF: Converter and Bean AutoComplete, JSF – Hello World, Auto Complete, Handling Exceptions on a WebApp, User Authentication (Filter/Servlet), Creating a WebServer.

In the end of the post you will find the link to download the source code of today’s post.

Today we will see two ways to send an object and/or a message after a redirect. We will use the Flash Scope (JSF 2.0 API) or creating a class to control the JSF phases (works on JSF 1.2 or a higher version).

Bellow you will see some images of the project screen shots and a few codes:

/*******************************************************************************
 * Copyright (c) 2010 Red Hat, Inc.
 * Distributed under license by Red Hat, Inc. All rights reserved.
 * This program is made available under the terms of the
 * Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Red Hat, Inc. - initial API and implementation
 ******************************************************************************/
package demo;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

/**
 * Created by JBoss Tools
 */
@ManagedBean(name="user")
@RequestScoped
public class User {
	private String name;

	public User() {
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String sayHello() {
		return "greeting";
	}
}
<?xml version="1.0" encoding="UTF-8"?>

<faces-config
    xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
	version="2.0">

	<navigation-rule>
		<from-view-id>/pages/inputname.xhtml</from-view-id>
		<navigation-case>
			<from-outcome>greeting</from-outcome>
			<to-view-id>/pages/greeting.xhtml</to-view-id>
		</navigation-case>
	</navigation-rule>

    <application>
        <resource-bundle>
            <base-name>resources</base-name>
            <var>msgs</var>
        </resource-bundle>
    </application>
</faces-config>

I will edit now the “faces-config.xml”; we will use the redirect to navigate between the pages. The code bellow will show how our file will be (take a look at the line 14):

<?xml version="1.0" encoding="UTF-8"?>

<faces-config
    xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
	version="2.0">

	<navigation-rule>
		<from-view-id>/pages/inputname.xhtml</from-view-id>
		<navigation-case>
			<from-outcome>greeting</from-outcome>
			<to-view-id>/pages/greeting.xhtml</to-view-id>
			<redirect/>
		</navigation-case>
	</navigation-rule>

    <application>
        <resource-bundle>
            <base-name>resources</base-name>
            <var>msgs</var>
        </resource-bundle>
    </application>
</faces-config>


Where is Peter? That is what happens when we use the redirect and the object is not in the session scope. To fix this “problem” we will use the not so popular Flash Scope.

Let us edit the User class (take a look at the lines 38, 39):

/*******************************************************************************
 * Copyright (c) 2010 Red Hat, Inc.
 * Distributed under license by Red Hat, Inc. All rights reserved.
 * This program is made available under the terms of the
 * Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Red Hat, Inc. - initial API and implementation
 ******************************************************************************/
package demo;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

import com.sun.faces.context.flash.ELFlash;

/**
 * Created by JBoss Tools
 */
@ManagedBean(name="user")
@RequestScoped
public class User {
	private String name;

	public User() {
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String sayHello() {
		// Put the object inside the flash scope
		ELFlash.getFlash().put("user", this);
		return "greeting";
	}
}

And to access the user object in the Flash Scope, you just have to edit your page:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">

	<ui:composition template="/templates/common.xhtml">
			<ui:define name="pageTitle">Greeting to User</ui:define>
			<ui:define name="pageHeader">Greeting Page</ui:define>
			<ui:define name="body">
				#{msgs.greeting} #{flash.user.name}!
			</ui:define>
	</ui:composition>
</html>

Now we will be able to meet Peter again:

The Flash scope keeps the object just like if it was a session scope. Pay attention to the fact that after you use the object “user” that is stored inside the flash scope, the object will be removed. How can you keep an object inside the Flash Scope after we use it? Piece of cake, just edit the invocation:

      #{flash.user.name}

For

      #{flash.keep.user.name}

If you use the last line your object will remain inside the Flash Scope.

To JSF 1.2: Unfortunately the only way to keep an object / message after a redirect (until today) is controlling it inside the session. =/ BUT, if you want just to send an alert (message) to the next screen there is another solution.

I will create another page to display the welcome message as an alert “<h:messages/>”. Take a look at our new code:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:ui="http://java.sun.com/jsf/facelets"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:ez="http://java.sun.com/jsf/composite/demo">

	<ui:composition template="/templates/common.xhtml">

		<ui:define name="pageTitle">Input User Name</ui:define>

		<ui:define name="pageHeader">JSF 2 Hello Application</ui:define>

		<ui:define name="body">
			<h:message showSummary="true" showDetail="false" style="color: red; font-weight: bold;" for="inputname" />
			<ez:input id="inputname" label="${msgs.prompt}" value="#{user.name}" action="#{user.sayHello}" submitlabel="Say Hello"/>
			<ez:input id="inputname2" label="${msgs.prompt}" value="#{user.name}" action="#{user.sayHelloWithAlert}" submitlabel="Say Hello With Alert"/>
		</ui:define>
	</ui:composition>
</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">

	<ui:composition template="/templates/common.xhtml">
			<ui:define name="pageTitle">Greeting to User With alert</ui:define>
			<ui:define name="pageHeader">Greeting Page With alert</ui:define>
			<ui:define name="body">
				<h:messages />
			</ui:define>
	</ui:composition>
</html>
/*******************************************************************************
 * Copyright (c) 2010 Red Hat, Inc.
 * Distributed under license by Red Hat, Inc. All rights reserved.
 * This program is made available under the terms of the
 * Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Red Hat, Inc. - initial API and implementation
 ******************************************************************************/
package demo;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;

import com.sun.faces.context.flash.ELFlash;

/**
 * Created by JBoss Tools
 */
@ManagedBean(name="user")
@RequestScoped
public class User {
	private String name;

	public User() {
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String sayHello() {
		// Put the object inside the flash scope
		ELFlash.getFlash().put("user", this);
		return "greeting";
	}

	public String sayHelloWithAlert() {
		String message = "Hello : " + name;
		FacesContext context = FacesContext.getCurrentInstance();

		context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, message, message));

		return "greetingWithAlert";
	}
}
<?xml version="1.0" encoding="UTF-8"?>

<faces-config
    xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
	version="2.0">

	<navigation-rule>
		<from-view-id>/pages/inputname.xhtml</from-view-id>
		<navigation-case>
			<from-outcome>greeting</from-outcome>
			<to-view-id>/pages/greeting.xhtml</to-view-id>
			<redirect/>
		</navigation-case>
		<navigation-case>
			<from-outcome>greetingWithAlert</from-outcome>
			<to-view-id>/pages/greetingWithAlert.xhtml</to-view-id>
		</navigation-case>
	</navigation-rule>

    <application>
        <resource-bundle>
            <base-name>resources</base-name>
            <var>msgs</var>
        </resource-bundle>
    </application>
</faces-config>


But, if we use the redirect action our message will not be displayed:

<?xml version="1.0" encoding="UTF-8"?>

<faces-config
    xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
	version="2.0">

	<navigation-rule>
		<from-view-id>/pages/inputname.xhtml</from-view-id>
		<navigation-case>
			<from-outcome>greeting</from-outcome>
			<to-view-id>/pages/greeting.xhtml</to-view-id>
			<redirect/>
		</navigation-case>
		<navigation-case>
			<from-outcome>greetingWithAlert</from-outcome>
			<to-view-id>/pages/greetingWithAlert.xhtml</to-view-id>
			<redirect/>
		</navigation-case>
	</navigation-rule>

    <application>
        <resource-bundle>
            <base-name>resources</base-name>
            <var>msgs</var>
        </resource-bundle>
    </application>
</faces-config>


The solution bellow I found in the site: “ocpsoft.com/java/persist-and-pass-facesmessages-over-page-redirects/”.

The class bellow will get your message and store it in the session scope. Once the message was displayed it will be removed from the session scope. This is a very useful solution to prolong the scope of a message:

package demo;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;

/**
 * Enables messages to be rendered on different pages from which they were set.
 *
 * After each phase where messages may be added, this moves the messages
 * from the page-scoped FacesContext to the session-scoped session map.
 *
 * Before messages are rendered, this moves the messages from the
 * session-scoped session map back to the page-scoped FacesContext.
 *
 * Only global messages, not associated with a particular component, are
 * moved. Component messages cannot be rendered on pages other than the one on
 * which they were added.
 *
 * To enable multi-page messages support, add a <code>lifecycle</code> block to your
 * faces-config.xml file. That block should contain a single
 * <code>phase-listener</code> block containing the fully-qualified classname
 * of this file.
 *
 * @author Jesse Wilson jesse[AT]odel.on.ca
 * @secondaryAuthor Lincoln Baxter III lincoln[AT]ocpsoft.com
 */
public class MultiPageMessagesSupport implements PhaseListener
{

    private static final long serialVersionUID = 1250469273857785274L;
    private static final String sessionToken = "MULTI_PAGE_MESSAGES_SUPPORT";

    public PhaseId getPhaseId()
    {
        return PhaseId.ANY_PHASE;
    }

    /*
     * Check to see if we are "naturally" in the RENDER_RESPONSE phase. If we
     * have arrived here and the response is already complete, then the page is
     * not going to show up: don't display messages yet.
     */
    // TODO: Blog this (MultiPageMessagesSupport)
    public void beforePhase(final PhaseEvent event)
    {
        FacesContext facesContext = event.getFacesContext();
        this.saveMessages(facesContext);

        if (PhaseId.RENDER_RESPONSE.equals(event.getPhaseId()))
        {
            if (!facesContext.getResponseComplete())
            {
                this.restoreMessages(facesContext);
            }
        }
    }

    /*
     * Save messages into the session after every phase.
     */
    public void afterPhase(final PhaseEvent event)
    {
        if (!PhaseId.RENDER_RESPONSE.equals(event.getPhaseId()))
        {
            FacesContext facesContext = event.getFacesContext();
            this.saveMessages(facesContext);
        }
    }

    @SuppressWarnings("unchecked")
    private int saveMessages(final FacesContext facesContext)
    {
        List<FacesMessage> messages = new ArrayList<FacesMessage>();
        for (Iterator<FacesMessage> iter = facesContext.getMessages(null); iter.hasNext();)
        {
            messages.add(iter.next());
            iter.remove();
        }

        if (messages.size() == 0)
        {
            return 0;
        }

        Map<String, Object> sessionMap = facesContext.getExternalContext().getSessionMap();
        List<FacesMessage> existingMessages = (List<FacesMessage>) sessionMap.get(sessionToken);
        if (existingMessages != null)
        {
            existingMessages.addAll(messages);
        }
        else
        {
            sessionMap.put(sessionToken, messages);
        }
        return messages.size();
    }

    @SuppressWarnings("unchecked")
    private int restoreMessages(final FacesContext facesContext)
    {
        Map<String, Object> sessionMap = facesContext.getExternalContext().getSessionMap();
        List<FacesMessage> messages = (List<FacesMessage>) sessionMap.remove(sessionToken);

        if (messages == null)
        {
            return 0;
        }

        int restoredCount = messages.size();
        for (Object element : messages)
        {
            facesContext.addMessage(null, (FacesMessage) element);
        }
        return restoredCount;
    }
}

And as our last action, let us edit the “faces-config.xml”:

<?xml version="1.0" encoding="UTF-8"?>

<faces-config
    xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
	version="2.0">

	<navigation-rule>
		<from-view-id>/pages/inputname.xhtml</from-view-id>
		<navigation-case>
			<from-outcome>greeting</from-outcome>
			<to-view-id>/pages/greeting.xhtml</to-view-id>
			<redirect/>
		</navigation-case>
		<navigation-case>
			<from-outcome>greetingWithAlert</from-outcome>
			<to-view-id>/pages/greetingWithAlert.xhtml</to-view-id>
			<redirect/>
		</navigation-case>
	</navigation-rule>
	<lifecycle>
		<phase-listener>demo.MultiPageMessagesSupport</phase-listener>
	</lifecycle>	

    <application>
        <resource-bundle>
            <base-name>resources</base-name>
            <var>msgs</var>
        </resource-bundle>
    </application>
</faces-config>

Deploy the application again and guess who is back? Peter! \o/

If you want to download the source code of this post, click here. To run this code, you will need to have the JBoss 6 configured in your Eclipse. But to set up the JBoss 6 in you Eclipse you will need the JBoss tools. If you need some help to install the JBoss Tools check this post: User Login Validation with JAAS and JSF.

I hope this post might help you.

If you have any question or comment just post it.

This post was based on:

  • Book: “Core JavaServer Faces” Chapter: “Redirection and Flash”
  • JSF source code generated by the JBoss tools
  • The class to persist the message through the redirect: “ocpsoft.com/”

See you soon! \o_

User Login Validation with JAAS and JSF

Hello, how are you?

In another post I have talked about a User validation using Servlet / Filter. Today we will see another way of doing it, we will use JSF and JAAS.

The JAAS validation uses the server as tools to validate the user, his password and the role that the user has. You will not need to validate the user (programmatically) at every http request.

He are the others posts about web in my blog: JSF: Converter and Bean AutoComplete, JSF – Hello World, Auto Complete, Handling Exceptions on a WebApp, User Authentication (Filter/Servlet), Creating a WebServer.

We will use today JSF, Postgres, Eclipse and JBoss AS 6:

I will use the JBoss Tools just to help us with the JSF and allow us to use the JBoss 6 inside the Eclipse. You can create all the code posted here and put the WAR inside the JBoss folder and run it without the need of the Eclipse. In the beginning of the post I have listed a link with a “how-to” about a JSF application.

I will not show how to install the Postgres database because it is out of the scope of this post, but you can use any database that you want like MySQL, SqlServer, Oracle, etc.

To install the JBoss you just have to unzip it and it will be ready to be used.

Unzip the Eclipse and install the JBoss Tools. It is a really helpful tool when we work with JBoss and JSF.

  •   To make it easier I have selected this two options:

  • Then Finish the installation.

To install the server just need to click in the tab “Servers” > New >Server

Select JBoss 6 > Next

Select the path where you unzipped your JBoss:

And click in the “Finish” button.

Let us create a new JSF project (File > New > Project). I will use a project created by the JBoss Tools. If you want to create a JSF project by yourself, check the link in the begging of this post about JSF.

I am naming the application “LoginJSF”, select JSF 2.0 and click in Finish.

The Eclipse will ask you if you want to change to the web view, I clicked on the “No” button. You can click Yes later to see this view.

The Eclipse will create an application with a basic navigation. Notice that the Eclipse already added your application to the server, if it did not added, click with the right button of the mouse on the project name > Run As > Run on Server. Select JBoss.


Run the server and access by the link: http://localhost:8080/LoginJSF/pages/inputname.jsf

Stop the JBoss and let us create 3 folders:

  • A folder with public access
  • A folder only to admin access
  • A folder to user and admin access

<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:composite="http://java.sun.com/jsf/composite">

    <h:head>
        I am public! [=
    </h:head>
    <h:body>
        Everyone can see me. \o/
    </h:body>
</html>
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:composite="http://java.sun.com/jsf/composite">

    <h:head>
        Yes master admin! Welcome!
    </h:head>
    <h:body>
        Let us run this business!
    </h:body>
</html>
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:composite="http://java.sun.com/jsf/composite">

    <h:head>
        Welcome mister user!
    </h:head>
    <h:body>
        <br/>
        Please, do not create any bugs, ok?! >=)
    </h:body>
</html>

Now let us start the JAAS configuration. Let us start editing the web.xml file indicating which folders are protected:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <display-name>LoginJSF</display-name>
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
        <url-pattern>*.jsf</url-pattern>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

    <!-- Protected Areas -->
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Only admins</web-resource-name>
            <url-pattern>/pages/protected/admin/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>ADMIN</role-name>
        </auth-constraint>
    </security-constraint>
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Users and admins</web-resource-name>
            <url-pattern>/pages/protected/user/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>ADMIN</role-name>
            <role-name>USER</role-name>
        </auth-constraint>
    </security-constraint>

    <!-- Validation By Form -->
    <login-config>
        <auth-method>FORM</auth-method>
        <form-login-config>
            <form-login-page>/pages/public/login.xhtml</form-login-page>
            <form-error-page>/pages/public/loginError.xhtml</form-error-page>
        </form-login-config>
    </login-config>

    <!-- Allowed Roles -->
    <security-role>
        <role-name>ADMIN</role-name>
    </security-role>
    <security-role>
        <role-name>USER</role-name>
    </security-role>

    <!-- Filter to get the user name and work with it -->
    <filter>
        <filter-name>LoginFilter</filter-name>
        <filter-class>com.filters.LoginFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>LoginFilter</filter-name>
        <url-pattern>/pages/protected/*</url-pattern>
    </filter-mapping>
</web-app>

We will need a page to login and another page to be displayed if any error happens. Take a closer look at web.xml and you will see these pages described there.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
    JSF 2 Login
</h:head>
<h:body>
    <p>Login to access secure pages:</p>
    <form method="post" action="j_security_check">
        <h:panelGrid columns="2">
            <h:outputLabel for="j_username" value="Username" />
            <input type="text" id="j_username" name="j_username" />
            <h:outputLabel for="j_password" value="Password" />
            <input type="password" id="j_password" name="j_password" />
            <input type="submit" name="submit" value="Login" />
        </h:panelGrid>
        <br />
    </form>
</h:body>
</html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
    JSF 2 Login
</h:head>
<h:body>
    <p>Ops! Check your user and password</p>
</h:body>
</html>

Let us create a java Filter that will catch the login (user name) that was typed. With this login (user name) you will be able to search for the user in the database and put it in the session.

package com.filters;

import java.io.IOException;

import javax.servlet.*;

import org.jboss.security.SecurityAssociation;

public class LoginFilter implements Filter {

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException,
            ServletException {

        String userName = SecurityAssociation.getPrincipal().getName();

        System.out.println("Yeeey! Get me here and find me in the database: " + userName);

        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
}

Let us create now our database tables.

I will use the simplest database possible, with only two tables and a few columns.
Create a database named LoginJSF and run the script bellow:

CREATE TABLE "users"
(
  "name" character varying(50),
  pass character varying(50)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE "users" OWNER TO postgres;

CREATE TABLE user_roles
(
  user_name character varying(50),
  role_name character varying
)
WITH (
  OIDS=FALSE
);
ALTER TABLE user_roles OWNER TO postgres;

Let us insert two users, one with the USER role and another with the ADMIN role:

INSERT INTO users("name", pass) VALUES ('user', 'user');
INSERT INTO users("name", pass) VALUES ('admin', 'admin');
INSERT INTO user_roles(user_name, role_name) VALUES ('user', 'USER');
INSERT INTO user_roles(user_name, role_name) VALUES ('admin', 'ADMIN');

We are almost there, have a little bit more of patient. [=

We need to edit the file “login-config.xml” of the JBoss. You will find this file at “/JBOSS_THAT_YOU_UNZIPPED/server/default/conf/“. Add the lines bellow near the other tags named “application-policy”:

<!-- Others application-policy -->

<!-- ..................... -->

<!-- Security Profile Of our Software-->
<application-policy name="LoginJSFRealm">
    <authentication>
        <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required">
            <module-option name="dsJndiName">java:/LoginJSFRealmDS</module-option>
            <module-option name="principalsQuery">select pass from users where name=?</module-option>
            <module-option name="rolesQuery">select role_name, 'Roles' from user_roles where user_name = ?</module-option>
        </login-module>
    </authentication>
</application-policy>

We just gave to the JBoss a Realm to use: LoginJSFRealm. Now we need to let the JBoss know that our app will use this Realm. Let us create a file named “jboss-web.xml” inside the folder WEB-INF with the code bellow:

<?xml version="1.0" encoding="UTF-8"?>
<jboss-web>
    <!-- Links with JBoss the Realm to use -->
    <security-domain>java:/jaas/LoginJSFRealm</security-domain>
</jboss-web>

In the file “login-config.xml” we informed the JBoss to use a datasource named “LoginJSFRealmDS”. Through this datasource the JBoss will connect to the database. Let us create a file named “LoginJSFRealm-ds.xml” inside the folder “/JBOSS_THAT_YOU_UNZIPPED/server/default/deploy/“:

<?xml version="1.0" encoding="UTF-8"?>

<datasources>
    <local-tx-datasource>
        <jndi-name>LoginJSFRealmDS</jndi-name>
        <connection-url>jdbc:postgresql://localhost:5432/LoginJSF</connection-url>
        <driver-class>org.postgresql.Driver</driver-class>
        <user-name>postgres</user-name>
        <password>YOUR_PASSWORD</password>
        <!-- sql to call when connection is created. Can be anything, select 1 is valid for PostgreSQL <new-connection-sql>select 1</new-connection-sql> -->

        <!-- sql to call on an existing pooled connection when it is obtained from pool. Can be anything, select 1 is valid for PostgreSQL <check-valid-connection-sql>select
            1</check-valid-connection-sql> -->

        <!-- corresponding type-mapping in the standardjbosscmp-jdbc.xml (optional) -->
        <metadata>
            <type-mapping>PostgreSQL 7.2</type-mapping>
        </metadata>
    </local-tx-datasource>
</datasources>

To finish this tutorial, copy the Postgres Driver JDBC 4 that you downloaded into the folder “/JBOSS_THAT_YOU_UNZIPPED/server/default/lib/“.

Let us run our application! \o/

Access the public link first: http://localhost:8080/LoginJSF/pages/public/public.html

Let us access the protected area where only the admin may enter: http://localhost:8080/LoginJSF/pages/protected/admin/admin.html

Type and user and the password and it is done. You will log in.

What if a USER accesses the admin URL? What will happen?

Try the same with the USER trough the URL: http://localhost:8080/LoginJSF/pages/protected/user/user.html
We cannot forget about the message that were be displayed in our console:
With the filter you will be able to search in your database for a user with the user name typed in the login page and put the user in the session.

Note 1: Your filter will be invoked only if the user login with success. The job to validate if the password/login is correct we leave to the JBoss.

Note 2: If you type the right login/password and the error page is displayed check again the JBoss datasource data, if the datasource name declared in the login-config.xml is the same declared in the file with the “-ds.xml” in its name, if the configurations inside the datasource are correct like: password, database, connection URL.

Note 3: Just after I finish the post I notice that I named the pages with html and not with xhtml (user.html,admin.html, pubilc.html). You can rename this pages and access again to see the JSF working (do not forget to change the link also before you access, it will finish with xhtml and not html). My bad! =/

I hope this post helps you.

Any doubt, question or suggestions just post it.

See you soon! \o_

JSF: Converter and Bean AutoComplete

JSF: Converter and AutoComplete Bean

Hello, how are you?

Today we will be talking about JSF Converters (a Converter is used in select tags – the famous “ComboBox” – and others) and Eclipse Bean AutoComplete.

Ps.: I will use the term ComboBox (in respect to other technologies – most of it Desktop – like Delphi), that named this component like that. But in web applications we do not use this kind of name.

We need to setup our applications first. I will be quick about some setup configurations and very meticulous about others configurations.

You will need to download a JSF implementation and a JSTL library. You may find them here Mojarra JSF and here JSTL. We already covered this subject (download the jar files) in this post Creating a WebServer, and covered also how to create a JSF application in a post named: JSF – Hello World, Auto Complete.

First, we must download the needed libraries (Mojarra JSF and JSTL). When you finish downloading the files, copy the jar files into the WEB-INF folder. (We did these steps of copying the jar files in the post Creating a WebServer and JSF – Hello World, Auto Complete).

Create a new Dynamic Web Project with the configurations just like in this image (I am using the most recent Eclipse/Tomcat version). Click on the Next button until you find this screen. Select the option “Disable Library Configuration” and click in the “Finish” button.

Let us add the libraries do the Build Path. Click in the Project > Properties. Then click on the Build Path menu, and the “Add Jars” button.

Select in the opened window the files “*.jar” that you will find in the WEB-INF/lib folder. Push the Ok button then close the properties window.

We have to edit the web.xml file (If the Eclipse did not create one web.xml for you, you just have to create the file in the WEB-INF folder and put the following text).

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">
    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.jsf</url-pattern>
        <url-pattern>/faces/*</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>faces/index.xhtml</welcome-file>
    </welcome-file-list>
</web-app>

Let us create a welcome page just to check if our application is configured correctly. Create a file named index.xhtml inside the WebContent folder. Copy the code bellow into the created file (you can override if there is any code inside there).

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html">

    <h:head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>Hellow World JSF 2.0</title>
    </h:head>

    <h:body>
        <h:form>
            <h:outputText value="Hello"/>
        </h:form>
    </h:body>
</html>

Start your application using the Tomcat server (if you do not know how to do it, check it here Creating a WebServer). Type this address in your web browser http://localhost:8080/PostJSF/. The index page will be displayed. If any error occurs it is better to you to start over again.

Maybe you will be asking: “What is a Converter? How we can use it?” Let us create a simple sample where we select a user in the first screen and show his name in the next screen. An error will happen…

Create a Java class named User in a package named “com”. This class will look like the code bellow:

package com;

public class User {

    public User(){

    }

    public User(String userName, String email){
        this.userName = userName;
        this.email = email;
    }

    private String userName;
    private String email;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return getUserName();
    }
}

Let us create a class to manage the request (UserMB); this class will have a User attribute and will show the server date in the other screen.

package com;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

@ManagedBean(name="userMB")
@RequestScoped
public class UserMB {

    private User user;
    private Map users;

    public UserMB(){
        users = new HashMap();
        users.put("Name 01", new User("Name 01", "Email 01"));
        users.put("Name 02", new User("Name 02", "Email 02"));
        users.put("Name 03", new User("Name 03", "Email 03"));
        users.put("Name 04", new User("Name 04", "Email 04"));
        users.put("Name 05", new User("Name 05", "Email 05"));
    }

    public String showName(){
        return "show.xhtml";
    }

    public Date getServerTime(){
        return new Date();
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public List getUsers() {
        return new ArrayList(users.values());
    }

    public User getUserByName(String userName){
        return users.get(userName);
    }
}

Once the managed bean it is invoked, we will create a map and insert some User objects inside it. These Users could be retrieved from a database.

Let us update our index.xhtml to look like the code bellow. We will be adding a select component with a list of the users coming from our managed bean.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"
        xmlns:f="http://java.sun.com/jsf/core">

    <h:head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>JSF 2.0</title>
    </h:head>

    <h:body>
        <h:form>
            <h:outputText value="Hello"/><br/>

            <h:selectOneMenu value="#{userMB.user}">
                 <f:selectItems value="#{userMB.users}"/>
            </h:selectOneMenu>

            <h:commandButton action="show.jsf" value="Go!"/>
        </h:form>
    </h:body>
</html>

Let us create a file named show.xhtml that will display the selected user name.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"
        xmlns:f="http://java.sun.com/jsf/core">

    <h:head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>JSF 2.0</title>
    </h:head>

    <h:body>
        <h:form>
            <h:outputText value="#{userMB.user.userName}"/><br/>
            <h:outputText value="#{userMB.serverTime}"/>
        </h:form>
    </h:body>
</html>

It is an obvious code. You only a select a user name in one page and show his name on the other page with the server date.

Let us run the application to see the result?

Look at your Eclipse console, there is an error message there: “severity=(ERROR 2), summary=(Conversion Error setting value for ‘null Converter’. ), detail=(Conversion Error setting value for ‘null Converter’. )”.

We need to get the selected value and convert it into a User object. After this conversion the JSF will “accept” the selection as a User Object. To create this converter, we will create a Java class that implements the Converter interface – this interfaces has two abstract methods.

Our converter will have the @FacesConverter annotation that the servers will use to locate it when the server starts up. The server will read the class as a Converter and make it available to our view (xhtml pages).

package com;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;

@FacesConverter(value="userConverter")
public class UserConverter implements Converter {

    @Override
    public Object getAsObject(FacesContext arg0, UIComponent arg1, String key) {
        FacesContext context = FacesContext.getCurrentInstance();
        UserMB userMB = (UserMB) context.getELContext().getELResolver().getValue(context.getELContext(), null, "userMB");

        return userMB.getUserByName(key);
    }

    @Override
    public String getAsString(FacesContext arg0, UIComponent arg1, Object arg2) {
        return arg2.toString();
    }
}

And we will edit our index.xhtml one last time. We must “tell” the select tag that it must use the Converter that we created.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"
        xmlns:f="http://java.sun.com/jsf/core">

    <h:head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <title>JSF 2.0</title>
    </h:head>

    <h:body>
        <h:form>
            <h:outputText value="Hello"/><br/>

            <h:selectOneMenu value="#{userMB.user}">
                 <f:selectItems value="#{userMB.users}"/>
                 <f:converter converterId="userConverter"/>
            </h:selectOneMenu>

            <h:commandButton action="#{userMB.showName}" value="Go!"/>
        </h:form>
    </h:body>
</html>

Let us run our application again and see what will happen?

Notice that in our code we do a search in the Users Map (UserMB), if necessary, we could use some Injected class in the UserMB to search in the database. Be aware of: A Converter will not do a resource injection, even if you use any kind of annotation. e.g.: @EJB. That is the reason that we invoke the Managed Bean and then, we find our User. You could use any resource inside the Managed Bean to search for the user. e.g.: database, file, etc.

A Converter is needed when we want to use an object through a method (like a set) originated from a select (ComboBox) or any other object that allows you to choose from a list of objects. The UserMB setUser is called and the Converter starts to work, through the “getAsObject” method – that having the object ID coming from the select – uses it to get the real object from the map.

How to activate the Eclipse Auto Complete when we talk about Java classes? The Auto Complete will work in classes that are managed by the JSF e.g. ManagedBean, Bundle, etc. You could notice already that our tags already have the auto complete working. (If you did not notice yet, just go to any xhtml file type “<h:” and press ctrl + space bar).

To activate the Auto Complete to java classes – e.g. when you write “#{userMB.user.}”, a list of methods and options will be displayed – we will need to edit our faces-config.xml and the UserMB.

In the UserMB we will just remove the “@ManagedBean” and “@RequestScoped” annotations. Our new class code will be:

package com;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class UserMB {

    private User user;
    private Map users;

    public UserMB(){
        users = new HashMap();
        users.put("Name 01", new User("Name 01", "Email 01"));
        users.put("Name 02", new User("Name 02", "Email 02"));
        users.put("Name 03", new User("Name 03", "Email 03"));
        users.put("Name 04", new User("Name 04", "Email 04"));
        users.put("Name 05", new User("Name 05", "Email 05"));
    }

    public String showName(){
        return "show.xhtml";
    }

    public Date getServerTime(){
        return new Date();
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public List getUsers() {
        return new ArrayList(users.values());
    }

    public User getUserByName(String userName){
        return users.get(userName);
    }
}

We just need to edit the faces-config.xml. We will need to add the Managed Bean into the xml file; to do this just click in the tab ManagedBean.

Select the “request” option and then click the button “add”. Type UserMB (our class will be displayed) select it and click in the finish button and save all your file updates.

Open the show.xhtml file, and inside the EL “#{userMB.user}” type a . (dot) and after the dot press ctrl + space bar and you will see the “magic”.

Do not think that by using xml instead annotations that you will be receding. Some Design Patterns says that using annotation is intrusive, and you are breaking the class cohesion. The class does not have to know the database behavior or configurations. One of the reasons that Spring/Hibernate/JPA/JSF allows the xml configurations is this kind of approach. The only thing that we did it was to inform the Managed Bean that we will use.

You will be able to edit your “faces-config.xml” through the interface that the Eclipse allows us to use.

A last topic about our subject is that your Project Facets must be checked as JSF. In this post we see how to change a Project Facets: JSF – Hello World, Auto Complete.

I hope this post might help you.

If you have any question, just post it.

See you soon.