Обработка параметров представления в JSF после сообщения

У меня есть несколько страниц, для работы которых требуется идентификатор пользователя, поэтому следующий код:

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(){

    }

}

Однако после вызова doAction параметр представления в URL-адресе исчезает. Бин по-прежнему работает из-за своей природы области просмотра, но это разрушает мои попытки навигации в будущем. Когда я ищу, у меня сложилось впечатление, что параметр просмотра должен оставаться после сообщения, таким образом читая userpage.jsf?userId=123, но это не так. Каково действительно предполагаемое поведение?

В связи с этим я пытался реализовать автоматическое добавление параметров представления при переходе на другую страницу, где я хочу сохранить идентификатор пользователя. Кажется, это работает для других, но для меня идентификатор пользователя в ViewRoot всегда равен нулю. Код ниже, используемый для получения параметра представления (i знаю, что я мог бы использовать свой временно сохраненный userId в bean-компоненте для навигации, но это решение было бы намного интереснее):

    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.

И последнее t мысль в том, что методы установки все еще работают,setUserId вызывается с правильным значением в сообщении.

Я совершенно не понял, как работают параметры просмотра, или здесь какая-то ошибка? Я думаю, что мой вариант использования должен быть крайне распространенным и иметь базовую поддержку в фреймворке.

12
задан Rasmus Franke 27 April 2012 в 14:35
поделиться