Novedades en JSF 2

La versión 6 del estándar JavaEE incorpora una importante actualización de Java Server Faces. En la red se pueden encontrar multitud de artículos de resumen de las novedades que incorpora JSF 2 así que más que un artículo he escrito una chuleta para tener a mano y recordar fácilmente los principales cambios. Así que publico esto realmente para no perderlo de vista y tenerlo fácilmente accesible.

Referencias

 Facelets

Soporte oficial para Facelets y de hecho es el mecanismo recomendado y estándar sobre JSP. Efectivamente la mayoría de las nuevas funcionalidades introducidas para JSF 2 sólo funcionaran si la página está escrita con facelets, para evitar los problemas de integración que históricamente se encontraban al combinar JSF y JSP.

https://facelets.dev.java.net/

Documentación oficial

 Ajax

Por fin JSF incorpora soporte oficial y nativo de Ajax. El tema merece un artículo aparte para poder entrar en más detalle. Próximamente.

JSF 2.0 introduces a simplification that reduces navigation-related grunge code: implicit navigation. If no matching navigation case is found after checking all available rules, the navigation handler checks to see whether the action outcome corresponds to a view id. If a view matching the action outcome is found, an implicit navigation to the matching view occurs.

O sea que podemos usar directamente el nombre o la ruta de una vista como resultado de una acción. Que al final es lo que hacíamos en la mayoría de las veces e implicaba bastante código.

<h:commandButton value="#{msgs.loginButtonText}" action="places"/>

La activación del botón representado por el anterior código saltaría a la página places.xhtml en el directorio relativo actual. Es recomendable utilizar rutas absolutas como en el siguiente ejemplo.

<h:commandButton value="#{msgs.loginButtonText}"    action="/pages/places"/>

Cargará /pages/places.xhtml

Obviamente esto también podemos aplicarlo al resultado de acciones dentro de un backing bean.Si queremos una redirección también podemos hacerlo sin editar el XML.

<h:commandButton id="loginButton"  
 value="#{msgs.loginButtonText}"
 action="/pages/places?faces-redirect=true"/>

The conditional navigation feature allows navigation cases to specify a pre-condition that must be met in order for the navigation case to be accepted. The pre-condition is specified as an EL expression using the new <if> configuration element:

<navigation-case>  
 <from-outcome>success</from-outcome>
 <to-view-id>/page2.xhtml</to-view-id>
 <if>#{foo.someCondition}</if>
</navigation-case>  

 Ámbitos

 View Scope

View scope is one of two new scopes introduced in JSF 2 that fall into the category of “longer than request, shorter than session” scopes. As the name implies, state that is placed into view scope is preserved until the user finishes interaction with the current view. If you have ever had the joy of trying to figure out why your command component isn’t firing after binding the rendered attribute to a request-scoped managed bean, view scope may just be the answer to your problems.

 Flash Scope

State that is placed into flash scope is propagated across a single view transition, including surviving redirects, and is cleaned up before moving on to yet another view. If you have been resorting to session scope to store state that needs to survive a redirect, flash scope might just be for you.

 Anotaciones

 Anotaciones en los Managed Bean

Antes:

<managed-bean>  
 <managed-bean-name>foo</managed-bean-name>
 <managed-bean-class>com.foo.Foo</managed-bean-class>
 <managed-bean-scope>session</managed-bean>
</managed-bean>  

Ahora:

@ManagedBean
@SessionScoped
public class Foo { }  

The name for the managed bean is automatically derived from the name of the annotated class. In the above example, the presence of @ManagedBean annotation on the Foo class makes a managed bean with the name “foo” available. Alternatively, the @ManagedBean annotation also allows a name to be specified explicitly.

Hay otras maneras de declarar un bean como gestionado y algunas pueden provocar problemas. No queda claro cual es la más recomendable, dependerá del entorno. YMMV.

Referencias entre managed beans o atributos gestionados (managed properties)

Si queremos hacer lo mismo que antes al declarar el propio bean (con el XML) y aplicar la idea a los atributos que tienen un valor inicial también podemos utilizar anotaciones. Además podemos utilizar una expresión EL que, habitualmente, hará referencia a otro bean.Aplicar la anotación @ManagedProperty al atributo.Crear un setter para el atributo (obligatorio)Recordar que el orden de inicialización del bean es: constructor, atributos y el método anotado con @PostConstructAsí que cuidado especialmente con el último punto, ya que si utilizamos el constructor para realizar inicializaciones aun no tendremos los atributos anotados con valores correctos.

@ManagedProperty("#{tablas}")
 private Tablas tablas;

 @PostConstruct
 public void init() {
   // aquí ya podemos utilizar 'tablas'.
 }

 Project Stage

Project stage is a new configuration option that allows the application developer/deployer to specify a hint to the JSF implementation regarding the role of the current deployment.This hint allows the JSF implementation to optimize its behavior for the current stage. For example, the JSF implementation might provide more verbose development-time diagnostics than would be practical for a production environment.

 Validación

 Validación de beans

JSF 2 provides built-in integration with JSR-303 (Bean Validation) constraints. In environments where a bean validation implementation is present, JSF automatically validates constraints for beans that are referenced by UIInput values.

 Validación de campos vacios

In previous JSF releases, Validators were not applied to EditableValueHolder components with null/empty submitted values. Unfortunately, this behavior limits the utility of constraints that actually check null/empty values, such as the JSR 303 @NotNull constraint. In order to support @NotNull and other similar constraints, JSF 2 changes the behavior of null/empty value validation. As of JSF 2, when a JSR-303 implementation is present, null/empty values are validated.

 Gestión de errores

The JSF 2 specification helps in this area with the introduction of the new ExceptionHandler API. JSF implementations are now required to allow all “unexpected” exceptions to propagate out of the current lifecycle phase so that they can be handled globally by an ExceptionHandler instance.

 Resource Bundles

http://java.dzone.com/articles/resource-bundles-jsf-20

Para definir un bundle por defecto para toda la aplicación utilizar lo siguiente en el faces-config.xml:

<application>  
    <resource-bundle>
      <base-name>net.sargue.app.web.messages</base-name>
      <var>msgs</var>
    </resource-bundle>
  </application>

Para utilizarlo desde un bean:

public class MessageProvider {  
  private ResourceBundle bundle;

  public ResourceBundle getBundle() {
     if (bundle == null) {
        FacesContext context = FacesContext.getCurrentInstance();
        bundle = context.getApplication().getResourceBundle(context, "msgs");
     }
     return bundle;
  }

  public String getValue(String key) {
     String result = null;
     try {
        result = getBundle().getString(key);
     } catch (MissingResourceException e) {
        result = "???" + key + "??? not found";
     }
     return result;
  }
}

 Carga de recursos (imágenes, CSS, JavaScripts...)

JSF 2 provides a standard mechanism for defining and accessing resources. You put your resources under a top-level directory named resources, and use some JSF 2 tags to access those resources in your views. The only requirement for a resource is that it reside in the resources directory or a subdirectory thereof. You can name subdirectories of the resources directory anything you want.

El nombre del directorio es el nombre de la "biblioteca" (library). Ejemplos de uso:

<h:outputStylesheet library="css" name="styles.css" target="body"/>  
<h:outputScript library="javascript" name="util.js" target="head"/>  
<h:graphicImage library="images" name="cloudy.gif"/>  

Componentes compuestos

Los componentes compuestos es una nueva características incorporada a JSF 2 gracias a la integración de facelets. Para no alargar el post publicaré un artículo separado con algunas notas y referencias sobre el tema.