tutorial template etiquetas español ejemplo jsf-2 viewparams

jsf 2 - template - Manejar los parámetros de vista en JSF después de la publicación



ui:composition primefaces (2)

Cuando busco, me da la impresión de que el parámetro de vista debe permanecer después de una publicación y leer userpage.jsf? UserId = 123, pero este no es el caso. ¿Cuál es realmente el comportamiento previsto?

Este comportamiento es correcto. La <h:form> genera un elemento HTML <form> con una URL de acción sin ningún parámetro de vista. La solicitud POST solo envía exactamente a esa URL. Si tiene la intención de mantener los parámetros de vista en la URL, básicamente hay 3 formas:

  1. Trae algo de magia ajax.

    <h:commandButton action="#{userPageController.doAction}" value="post"> <f:ajax execute="@form" render="@form" /> </h:commandButton>

    De esta forma, la página solicitada inicialmente y, por lo tanto, también la URL de solicitud en la barra de direcciones del navegador permanece igual todo el tiempo.

  2. Si corresponde (por ejemplo, para la navegación de página a página), includeViewParams=true en una solicitud GET y usa includeViewParams=true . Puede usar <h:link> y <h:button> para esto:

    <h:button outcome="nextview?includeViewParams=true" value="post" />

    Sin embargo, esto tiene un exploit de seguridad EL en versiones de Mojarra anteriores a 2.1.6. Asegúrese de estar utilizando Mojarra 2.1.6 o posterior. Ver también el número 2247 .

  3. Controle la generación de URL de acción de <h:form> usted mismo. Proporcione un ViewHandler personalizado (simplemente extienda ViewHandlerWrapper ) en donde usted hace el trabajo en getActionURL() .

    public String getActionURL(FacesContext context, String viewId) { String originalActionURL = super.getActionURL(context, viewId); String newActionURL = includeViewParamsIfNecessary(context, originalActionURL); return newActionURL; }

    Para que se ejecute, regístrelo en faces-config.xml siguiente manera:

    <application> <view-handler>com.example.YourCustomViewHandler</view-handler> </application>

    Esto es también lo que está haciendo OmniFaces <o:form> . Admite un atributo includeViewParams adicional que incluye todos los parámetros de vista en la URL de acción del formulario:

    <o:form includeViewParams="true">

Actualización : la obtención de los parámetros de vista de la vista actual mediante programación (que es básicamente su segunda pregunta) debe hacerse de la siguiente manera:

Collection<UIViewParameter> viewParams = ViewMetadata.getViewParameters(FacesContext.getCurrentInstance().getViewRoot()); for (UIViewParameter viewParam : viewParams) { String name = viewParam.getName(); Object value = viewParam.getValue(); // ... }

Tengo algunas páginas que necesitan un userId para funcionar, por lo tanto, el siguiente código:

userpage.xhtml

<!-- xmlns etc. omitted --> <html> <f:metadata> <f:viewParam name="userId" value="#{userPageController.userId}"/> </f:metadata> <f:view contentType="text/html"> <h:head> </h:head> <h:body> <h:form> <h:commandButton action="#{userPageController.doAction}" value="post"/> </h:form> </h:body> </f:view>

userPageController.java

@Named @ViewScoped public class userPageControllerimplements Serializable { private static final long serialVersionUID = 1L; @Inject protected SessionController sessionController; @Inject private SecurityContext securityContext; @Inject protected UserDAO userDAO; protected User user; protected Long userId; public UserPage() { } public User getUser() { return user; } public void setUser(User user) { this.user = user; } public Long getUserId() { return userId; } public void setUserId(Long userId) { if(!FacesContext.getCurrentInstance().isPostback()){ User u = userDAO.find(userId); this.userId = userId; this.user = u; } } public void doAction(){ } }

Sin embargo, después de llamar a doAction, el parámetro de vista en la url desaparece. El bean todavía funciona debido a su naturaleza viewcoped, pero arruina mis intentos de navegación futura. Cuando busco, me da la impresión de que el parámetro de vista debe permanecer después de una publicación y leer userpage.jsf? UserId = 123, pero este no es el caso. ¿Cuál es realmente el comportamiento previsto?

En relación con esto, he tratado de implementar la adición automática de parámetros de vista cuando navego a otra página donde deseo mantener el ID de usuario. Parece que funciona para otros, pero para mí, el ID de usuario en ViewRoot siempre es nulo. El siguiente código se usa para recuperar el parámetro de vista (sé que podría usar mi userId almacenado temporalmente en el bean para la navegación, pero esta solución sería mucho más elegante):

String name = "userId"; FacesContext ctx = FacesContext.getCurrentInstance(); ViewDeclarationLanguage vdl = ctx.getApplication().getViewHandler().getViewDeclarationLanguage(ctx, viewId); ViewMetadata viewMetadata = vdl.getViewMetadata(ctx, viewId); UIViewRoot viewRoot = viewMetadata.createMetadataView(ctx); UIComponent metadataFacet = viewRoot.getFacet(UIViewRoot.METADATA_FACET_NAME); // Looking for a view parameter with the specified name UIViewParameter viewParam = null; for (UIComponent child : metadataFacet.getChildren()) { if (child instanceof UIViewParameter) { UIViewParameter tempViewParam = (UIViewParameter) child; if (name.equals(tempViewParam.getName())) { viewParam = tempViewParam; break; } } } if (viewParam == null) { throw new FacesException("Unknown parameter: ''" + name + "'' for view: " + viewId); } // Getting the value String value = viewParam.getStringValue(ctx); // This seems to ALWAYS be null.

Una última idea es que los métodos setter todavía parecen funcionar, setUserId se llama con el valor correcto en la publicación.

¿He entendido por completo cómo funcionan los parámetros de vista, o hay algún tipo de error aquí? Creo que mi caso de uso debería ser extremadamente común y tener soporte básico en el marco.


¿Tengo razón en que para la solución 1 <f:ajax execute="@form" render="@form" /> para trabajar también habría que incluir algo así como

<f:param name="userId" value="#{userPageController.userId}"/>

dentro de la <h:commandButton> ?

Como se describe en https://.com/a/14026995/811046