JSF2.3 form – Ejemplos
En JSF la etiqueta <h: form> representa un formulario HTML <form> en el navegador. Este formulario puede incluir otros componentes de entrada que pueden recopilar datos y declarar atributos.
Generalmente en aplicaciones web se hace uso de formulario/os para enviar datos. La etiqueta <h: form> es el componente responsable de permitir que etiquetas como h:commandButton envíen datos al servidor.
Si solamente colocamos la etiqueta <h:form/> tenemos:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:pt="http://xmlns.jcp.org/jsf/passthrough" > <h:head> <title>Ejemplo JSF2.3 Form</title> </h:head> <h:body> <h:form /> </h:body> </html>
Código HTML generado:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head id="j_idt2"> <title>Ejemplo Form</title> </head> <body> <form id="j_idt5" name="j_idt5" method="post" action="/ejemplo_web_jsf23/ejemploForm.xhtml" enctype="application/x-www-form-urlencoded"> <input type="hidden" name="j_idt5" value="j_idt5" /> <input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="-4139786714383868648:-509728107214033242" autocomplete="off" /> </form> </body> </html>
Vamos a analisar el código generado:
id=»j_idt5″, es el identificador del formulario. Este valor fue creado por el servidor. Si hubiéramos colocado un id manualmente, este substituye al valor creado. Ejemplo <h:form id=»formulario»>
name=»j_idt5″, es el nombre del formulario.
method=»post», todos los envíos de formularios JSF se implementan con el método POST.
action=»/ejemplo_web_jsf23/ejemploForm.xhtml», aunque la etiqueta de formulario HTML tiene atributo action, h: form puede guardar el estado en el servidor o en el cliente (una opción que se implementa como un campo oculto).
enctype=»application/x-www-form-urlencoded», es el tipo de contenido por defecto que se usa para el envio de datos. Los caracteres se codifican antes de enviarse (los espacios se convierten en símbolos + y los caracteres especiales se convierten en valores ASCII hexadecimal). Otros valores que puede tomar este atributo: mulipart / form-data: No se codifican caracteres. Este valor es obligatorio cuando el formularios tienen control de carga de archivos. text/plain: los espacios se convierten en símbolos +, no se codifican caracteres especiales.
<input type=»hidden» name=»javax.faces.ViewState» id=»j_id1:javax.faces.ViewState:0″ value=»-4139786714383868648:-509728107214033242″ autocomplete=»off» />, campo oculto que guarda el estado de la vista (arbol de componentes) en el servidor.
Cuando enviamos la primera requisición HTTP GET (osea http://localhost:8080/ejemplo_web_jsf23/ejemploForm.xhtml) al controlador JSF, nuestro arbol de componente es creado. Como respuesta el controlador JSF nos retorna un HTML que contiene un campo oculto (<input type=»hidden» name=»javax.faces.ViewState» id=»j_id1:javax.faces.ViewState:0″ value=»-4139786714383868648:-509728107214033242″ autocomplete=»off» />). Este campo oculto contiene el ID del arbol de componentes en el atributo value (En el ejemplo: value=»-4139786714383868648:-509728107214033242″). Si enviamos otra requisición, este atributo cambiará. Esto indica que cada requisición crea un arbol de componente y estas son almacenadas en el servidor.
Si hacemos muchas veces estas requisiciones, probablemente tendremos en el servidor un «Java Heap Space» (Desbordamiento de memoria). Mismo, si limitando el servidor para pocas requisiciones por usuário, no es buena idea almacenar el arbol de componentes en el servidor.
Para evitar esto, JSF nos da otra alternativa. El arbol de componentes en este caso, seria serializada en el cliente y enviada al servidor de forma serializada. Para habilitar la serialización del arbol de componentes en el cliente, adicionamos javax.faces.STATE_SAVING_METHOD al archivo web.xml, tal como es mostrado en la figura siguiente.
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0"> <display-name>ejemplo_web_jsf23</display-name> <context-param> <param-name>javax.faces.STATE_SAVING_METHOD</param-name> <param-value>client</param-value> </context-param> <welcome-file-list> <welcome-file>index.xhtml</welcome-file> </welcome-file-list> <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>/faces/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.xhtml</url-pattern> </servlet-mapping> </web-app>
Despues de cambiar la configuración en el archivo web.xml, reiniciamos el servidor y enviamos nuestra requisición del ejemplo anterior.
Código HTML generado:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head id="j_idt2"> <title>Ejemplo JSF2.3 Form</title></head> <body> <form id="j_idt5" name="j_idt5" method="post" action="/ejemplo_web_jsf23/ejemploForm.xhtml" enctype="application/x-www-form-urlencoded"> <input type="hidden" name="j_idt5" value="j_idt5" /> <input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="CeMu7jMLJOLF/KdrI5myPbbEE7DSK1MlotOOK8W2i6bkV0r4h05mW85aU1GApwExhmv4tX4Oc 4LXHIUixmH3RIaC3eE64Fq+K0TFuSx235AQH6eeyaiVNmxteCnbzWq7BCvjHmrf7SjAK74g24 dIQACuUi1YU/CkW3+DcQ+s3u0m55p8tMMeMFLrZ7OYaXPOA78Iw9nLD/5f9zI4wtq8QnLLf3x zmBMf5MOVrr1E3Kn02j2CN1yoQ4vEUtRZ1lpAinBDP5kg7QndH8ppkhej4VYmN+NoUyVPhm55n 5Z7Cdk=" autocomplete="off" /> </form> </body> </html>
Ahora el atributo value del campo oculto contiene la serialización. Este valor serializado corresponde al arbol de componentes.
La documentación del la implementación de JSF (mojarra) recomienda usar la configuración web.xml por el lado del cliente. De esta manera se economiza el uso de la memoria en el servidor.