O que é JSF ?
Quais os "módulos" que compõem o JSF?
Divisão de papéis com JSF ?
O que JSF trás de bom?
O que temos de diferente com JSF ?
Curiosidade
Como a especificação do JSF se ajusta
O que tenho que saber para começar a discutir e implementar aplicações usando o
faces ?
UIComponents e core tags

Regras de navegação:
<navigation-rule>
<from-view-id>/greeting.jsp</from-view-id>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/response.jsp</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>fail</from-outcome>
<to-view-id>/fail.jsp</to-view-id>
</navigation-case>
</navigation-rule>
BackBean:
JSP:
<h:inputText id="email" value="#{checkoutFormBean.email}"
size="25" maxlength="125"
validator="#{checkoutFormBean.validateEmail}"/>
Backbean:
public void validateEmail(FacesContext context, UIInput toValidate) {
String message = "";
String email = (String) toValidate.getValue();
if (email.indexOf('@') == -1) {
toValidate.setValid(false);
message = CoffeeBreakBean.loadErrorMessage(context,
CoffeeBreakBean.CB_RESOURCE_BUNDLE_NAME,"EMailError");
context.addMessage(toValidate.getClientId(context),new FacesMessage(message, ""));
} else {
toValidate.setValid(true);
}
}
Action Event Handler Method: métodos que recebem um ActionEvent e são void (não procuram nenhuma regra de negação, voltam para a mesma página).
- Apenas os componentes que implementam ActionSource podem usar esse método.
- UICommand e UIButton
JSP:
<h:commandLink id="NAmerica" action="bookstore"
actionListener="#{localeBean.chooseLocaleFromLink}">
Backbean:
public void chooseLocaleFromLink(ActionEvent event) {
String current = event.getComponent().getId();
FacesContext context = FacesContext.getCurrentInstance();
context.getViewRoot().setLocale((Locale)
locales.get(current));
}
JSP:
<h:inputText
id="name"
size="50"
value="#{cashier.name}"
required="true"
valueChangeListener="#{cashier.processValueChange}" />
</h:inputText>
Backbean:
public void processValueChange(ValueChangeEvent event)
throws AbortProcessingException {
if (null != event.getNewValue()) {
FacesContext.getCurrentInstance().
getExternalContext().getSessionMap().
put("name", event.getNewValue());
}
}
Navigation handling methods
(Action methods): métodos que retornam uma String que deve casar com as regras de navegação:JSP:
<h:commandButton
value="#{bundle.Submit}"
action="#{cashier.submit}" />
Backbean:
public String submit() {
...
if(cart().getTotal() > 100.00 &&
!specialOffer.isRendered())
{
specialOfferText.setRendered(true);
specialOffer.setRendered(true);
return null;
} else if (specialOffer.isRendered() &&
!thankYou.isRendered()){
thankYou.setRendered(true);
return null;
} else {
clear();
return ("receipt");
}
}
Arquivo de configuração do faces:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE faces-config PUBLIC
"-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
"http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
<faces-config>
<managed-bean>
<managed-bean-name>tabularBB</managed-bean-name>
<managed-bean-class>com.groundside.jsf.backing.Tabular</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>neighbors</managed-bean-name>
<managed-bean-class>com.groundside.jsf.Neighbors</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>editBB</managed-bean-name>
<managed-bean-class>com.groundside.jsf.backing.Edit</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>editContact</managed-bean-name>
<managed-bean-class>com.groundside.jsf.Contact</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
<navigation-rule>
<from-view-id>/tabular.jsp</from-view-id>
<navigation-case>
<from-outcome>drilldown</from-outcome>
<to-view-id>/edit.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>/edit.jsp</from-view-id>
<navigation-case>
<from-outcome>return</from-outcome>
<to-view-id>/tabular.jsp</to-view-id>
</navigation-case>
</navigation-rule>
</faces-config>
Entendendo o ciclo de vida
em todo jsp temos que ter: // tags dos tlds ... <f:view> // as tags do faces e tags que não são do faces também </f:view>
Exemplo comentado:
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<html>
<f:view>
<body>
<h:form>
<table>
<tr>
<td>
<h:outputText value="Login"/>
</td>
<td>
<h:inputText id="login" binding="#{cadastroBean.loginComponente}" required="true"/>
<h:message for="login"/>
</td>
</tr>
<tr>
<td>
<h:outputText value="Senha"/>
</td>
<td>
<h:inputSecret id="senha" value="#{cadastroBean.senha}" required="true"/>
<h:message for="senha"/>
</td>
</tr>
<tr>
<td>
<h:outputText value="E-mail" />
</td>
<td>
<h:inputText id="mail" value="#{cadastroBean.mail}" required="true"/>
<h:message for="mail"/>
</td>
</tr>
<tr>
<td>
<h:commandButton action="#{cadastroBean.cadastraUsuarioAction}" value="Enviar Dados"/>
</td>
</tr>
</table>
</h:form>
<h:form id="removeUsuario">
<h:dataTable var="usuario" value="#{cadastroBean.usuariosCadastrados}" border="1">
<h:column>
<f:facet name="header">
<h:outputText value="Login"/>
</f:facet>
<h:outputText value="#{usuario.login}"></h:outputText>
<f:facet name="footer">
<h:outputText value="Login"/>
</f:facet>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="E-mail"/>
</f:facet>
<h:outputText value="#{usuario.mail}"></h:outputText>
<f:facet name="footer">
<h:outputText value="E-mail"/>
</f:facet>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Ação"/>
</f:facet>
<h:commandLink value="#{usuario.id}" actionListener="#{cadastroBean.removeUsuarioAction}">
<h:outputText value="Excluir"></h:outputText>
</h:commandLink>
<f:facet name="footer">
<h:outputText value="Ação"/>
</f:facet>
</h:column>
</h:dataTable>
</h:form>
<body>
</f:view>
<html>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib
uri="http://java.sun.com/jsf/html" prefix="h" %>
<h:inputSecret
id="senha" value="#{cadastroBean.senha}"
required="true"/> <h:message for="senha"/>
<h:form id="removeUsuario">
<h:dataTable var="usuario" value="#{cadastroBean.usuariosCadastrados}" border="1">
<h:column>
<f:facet name="header">
<h:outputText value="Login"/>
</f:facet>
<h:outputText value="#{usuario.login}"></h:outputText>
<f:facet name="footer">
<h:outputText value="Login"/>
</f:facet>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="E-mail"/>
</f:facet>
<h:outputText value="#{usuario.mail}"></h:outputText>
<f:facet name="footer">
<h:outputText value="E-mail"/>
</f:facet>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Ação"/>
</f:facet>
<h:commandLink value="#{usuario.id}" actionListener="#{cadastroBean.removeUsuarioAction}">
<h:outputText value="Excluir"></h:outputText>
</h:commandLink>
<f:facet name="footer">
<h:outputText value="Ação"/>
</f:facet>
</h:column>
</h:dataTable>
</h:form>
package daca.bean;
public class Usuario {
private int id ;
private String login="";
private String senha="";
private String mail="";
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getSenha() {
return senha;
}
public void setSenha(String senha) {
this.senha = senha;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
}
package daca.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import daca.bean.Usuario;
/*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class GerenteBanco{
private DriverManagerDataSource dataSource;
public GerenteBanco(){
}
/* (non-Javadoc)
* @see daca.service.PersistenteIF#save(daca.business.Usuario)
*/
public void save(Usuario usuario) {
try {
Connection conn = dataSource.getConnection() ;
PreparedStatement statement = conn.prepareStatement("insert into usuario (login,senha,mail) values (?,?,?)");
statement.setString(1,usuario.getLogin());
statement.setString(2,usuario.getSenha());
statement.setString(3,usuario.getMail());
statement.execute();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
/* (non-Javadoc)
* @see daca.service.PersistenteIF#remove(java.lang.String)
*/
public void remove(String id) {
try {
Connection conn = dataSource.getConnection();
PreparedStatement statement = conn.prepareStatement("delete from usuario where id=?");
statement.setString(1,id);
statement.execute();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
/* (non-Javadoc)
* @see daca.service.PersistenteIF#selectTodos()
*/
public List selectTodos() {
Connection conn = null;
List lista = new ArrayList();
try {
conn = dataSource.getConnection();
ResultSet rs = conn.createStatement().executeQuery("select * from usuario");
while(rs.next()){
Usuario u = new Usuario();
u.setId(rs.getInt(1));
u.setLogin(rs.getString(2));
u.setSenha(rs.getString(3));
u.setMail(rs.getString(4));
lista.add(u);
}
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
return lista;
}
/**
* @return Returns the dataSource.
*/
public DriverManagerDataSource getDataSource() {
return dataSource;
}
/**
* @param dataSource The dataSource to set.
*/
public void setDataSource(DriverManagerDataSource dataSource) {
this.dataSource = dataSource;
}
}
package daca.service;
import javax.servlet.ServletContext;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import daca.dao.GerenteBanco;
import daca.util.DCContants;
import daca.util.FacesUtils;
/**
* The implementation of <code>ServiceLocator</code>.
* <p>
* This class is managed by the JSF managed bean facility,
* and is set with application scope.
*
* @see ServiceLocator
*/
public class ServiceLocator {
//the Spring application context
private ApplicationContext appContext;
//the cached user service
private GerenteBanco persistentService;
/**
* Constructor.
* <p>
* The following steps being done:
* <ul>
* <li>retrieve Spring application context from servlet context.
* <li>look up <code>UserService</code> from Spring applicatino context.
* </ul>
*/
public ServiceLocator() {
ServletContext context = FacesUtils.getServletContext();
this.appContext = WebApplicationContextUtils.getRequiredWebApplicationContext(context);
persistentService = (GerenteBanco)this.lookupService(DCContants.PERSISTENT_SERVICE_BEAN_NAME);
}
/**
* Lookup service based on service bean name.
*
* @param serviceBeanName the service bean name
* @return the service bean
*/
public Object lookupService(String serviceBeanName) {
return appContext.getBean(serviceBeanName);
}
public GerenteBanco getPersistentService() {
return persistentService;
}
public void setPersistentService(GerenteBanco persistentService) {
this.persistentService = persistentService;
}
}
package daca.util;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;
/**
* Utility class for JavaServer Faces.
*/
public class FacesUtils {
/**
* Get servlet context.
*
* @return the servlet context
*/
public static ServletContext getServletContext() {
return (ServletContext)FacesContext.getCurrentInstance().getExternalContext().getContext();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"><beans>
<!-- ========================= Start of PERSISTENCE DEFINITIONS ========================= -->
<!-- DataSource Definition -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource" destroy-method="close">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql:///daca</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value></value>
</property>
</bean>
<!-- PErsistent Service Defintion -->
<bean id="servicoPersistencia" class="daca.dao.GerenteBanco">
<property name="dataSource"><ref local="dataSource"/></property>
</bean>
</beans>
<?xml version="1.0"?>
<!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
"http://java.sun.com/dtd/web-facesconfig_1_0.dtd">
<faces-config>
<application>
<locale-config>
<default-locale>br</default-locale>
</locale-config>
<message-bundle>daca.bundle.Messages</message-bundle>
</application>
</faces-config>
<?xml version="1.0"?>
<!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
"http://java.sun.com/dtd/web-facesconfig_1_0.dtd">
<faces-config>
<managed-bean>
<description>
Service locator of the business services
</description>
<managed-bean-name>serviceLocatorBean</managed-bean-name>
<managed-bean-class>daca.service.ServiceLocator</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
</managed-bean>
<managed-bean>
<description>
</description>
<managed-bean-name>cadastroBean</managed-bean-name>
<managed-bean-class>daca.view.CadastroBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>service</property-name>
<value>#{serviceLocatorBean}</value>
</managed-property>
</managed-bean>
</faces-config>
<?xml version="1.0"?>
<!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
"http://java.sun.com/dtd/web-facesconfig_1_0.dtd">
<faces-config>
<navigation-rule>
<from-view-id>*</from-view-id>
<navigation-case>
<description>
</description>
<from-outcome>sucesso</from-outcome>
<to-view-id>/index.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<!--
<from-view-id>/algumaPagina.jsp</from-view-id>
<navigation-case>
<description>
</description>
<from-outcome>nomeLugar</from-outcome>
<to-view-id>/umaPagina.jsp</to-view-id>
</navigation-case>
</navigation-rule>
-->
</faces-config>
<?xml version="1.0"?>
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>Daca</display-name>
<description>
Aplicação Exemplo DACA
</description>
<welcome-file-list>
<welcome-file>index.jsf</welcome-file>
</welcome-file-list>
<!-- JavaServer Faces -->
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>
<context-param>
<param-name>javax.faces.CONFIG_FILES</param-name>
<param-value>/WEB-INF/faces-config.xml,/WEB-INF/faces-managed-beans.xml,/WEB-INF/faces-navigation.xml</param-value>
</context-param>
<context-param>
<param-name>com.sun.faces.validateXml</param-name>
<param-value>true</param-value>
</context-param>
<listener>
<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
</listener>
<!-- Faces Servlet -->
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Spring Servlet-->
<servlet>
<servlet-name>SpringContextServlet</servlet-name>
<servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Faces Servlet Mapping -->
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
<!-- Tomcat 4.1 can not read tld file from jar for jstl1.0 jarkata implementation. It's a workaround here. -->
<taglib>
<taglib-uri>http://java.sun.com/jstl/core</taglib-uri>
<taglib-location>/WEB-INF/c.tld</taglib-location>
</taglib>
</web-app>
package daca.view;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import javax.faces.component.html.HtmlCommandLink;
import javax.faces.component.html.HtmlInputText;
import javax.faces.event.ActionEvent;
import org.apache.commons.beanutils.BeanUtils;
import daca.bean.Usuario;
import daca.dao.GerenteBanco;
import daca.service.ServiceLocator;
import daca.util.DCContants;
public class CadastroBean {
private HtmlInputText loginComponente;
private String login="";
private String senha="";
private String mail="";
private int idParaRemocao;
private ServiceLocator service;
private List usuariosCadastrados = new ArrayList();
public String cadastraUsuarioAction(){
setLogin((String) getLoginComponente().getValue());
service.getPersistentService().save(createUsuarioBussiness());
return DCContants.PAGINA_CADASTRO;
}
public void removeUsuarioAction(ActionEvent event){
HtmlCommandLink link = (HtmlCommandLink) event.getSource();
getService().getPersistentService().remove( ((Integer)link.getValue()).toString() );
}
/**
* cria um usuario do model
* @return usuario, o usuário criado com os dados do form
*/
public Usuario createUsuarioBussiness(){
//TODO usar uma factory, tirar os printStackTrace
Usuario u = new Usuario();
try {
BeanUtils.copyProperties(u, this);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
reset();
return u ;
}
public void reset() {
setLoginComponente(new HtmlInputText());
setMail("");
setSenha("");
}
public HtmlInputText getLoginComponente() {
return loginComponente;
}
public void setLoginComponente(HtmlInputText loginComponente) {
this.loginComponente = loginComponente;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
public String getSenha() {
return senha;
}
public void setSenha(String senha) {
this.senha = senha;
}
public List getUsuariosCadastrados() {
usuariosCadastrados = service.getPersistentService().selectTodos();
return usuariosCadastrados;
}
public void setUsuariosCadastrados(List usuariosCadastrados) {
this.usuariosCadastrados = usuariosCadastrados;
}
public ServiceLocator getService() {
return service;
}
public void setService(ServiceLocator service) {
this.service = service;
}
}
Finalizando
Chamar na página
<h:outputText id=version value="#{initParam.versionNo}"
web.xml file
<context-param>
<param-name>versionNo</param-name>
<param-value>1.05</param-name>
</context-param>
<h:inputText id="userNo" value="#{UserNumberBean.userNumber}"
validator="#{UserNumberBean.validate}"/>
<h:inputText id="userNo" value="#{UserNumberBean.userNumber}">
<f:validateLength maximum="6" minimum="2"/>
</h:inputText>
Método validate que deve ser implementado no bean:
public void validateEmail(FacesContext context,UIInput toValidate) {
String message = "";
String email = (String) toValidate.getValue();
if (email.indexOf('@') == -1) {
toValidate.setValid(false);
message = CoffeeBreakBean.loadErrorMessage(context,
CoffeeBreakBean.CB_RESOURCE_BUNDLE_NAME,"EMailError");
context.addMessage(toValidate.getClientId(context),new FacesMessage(message, ""));
} else {
toValidate.setValid(true);
}
}
na sua página jsp chamar o método de validação:
<h:inputText id="email" value="#{checkoutFormBean.email}"
size="25" maxlength="125"
validator="#{checkoutFormBean.validateEmail}"/>
<f:loadBundle basename="carstore.bundles.Resources" var="bundle"/> <h:outputText value="bundle.key"/>
Finalmente: