Java Server Faces (JSF)

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);
  }
}

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" %>

 




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: