tengo unas pocas páginas que necesita un nombre de usuario para trabajar, por lo tanto el siguiente código:Manejo de los parámetros de vista en JSF después del post
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, traté de implementar la adición automática de parámetros de vista al navegar 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. Código de abajo utiliza para recuperar el viewparameter (Sé que podría utilizar mi ID de usuario se almacena temporalmente en el grano para la navegación, pero esta solución sería mucho más elaborado):
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 reflexión es que los métodos setter todavía parecen trabajo, 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.
Creo tercera es opciones conocidas. – kosa
Probablemente usaré 1. para manejar el problema de la barra url. Aproximadamente 2: sería una solución limpia para ver el manejo de los parámetros, pero solo funciona cuando se usa el mismo bean administrado para 2 páginas (algo que creo que normalmente es una mala opción), por lo que es inútil. Lo más probable es que termine definiendo los parámetros manualmente en cada enlace. ¿Tiene alguna idea de que el código en la parte inferior no funciona? Obtener el parámetro de vista programáticamente que es. –
Es porque estás creando una vista completamente nueva y en lugar de usar la vista actual. Ver respuesta actualizada. – BalusC