Обработка параметров просмотра в JSF после публикации

У меня есть несколько страниц, которым нужно работать с userId, таким образом, следующий код:

userpage.xhtml

              

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, но это не так. Каково действительно предполагаемое поведение?

В связи с этим я попытался реализовать автоматическое добавление параметров вида при переходе на другую страницу, где я хочу сохранить userId. Кажется, что это работает для других, но для меня userId в ViewRoot всегда имеет значение null. Код ниже используется для извлечения viewparameter (я знаю, что я мог бы использовать временно сохраненный 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. 

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

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

    Когда я ищу вокруг, у меня создается впечатление, что параметр просмотра должен оставаться после сообщения, таким образом, считывая userpage.jsf? UserId = 123, но это не так. Каково действительно предполагаемое поведение?

    Это правильно. генерирует элемент HTML

    с URL-адресом действия без каких-либо параметров представления. Запрос POST просто отправляет именно этот URL. Если вы намерены сохранить параметры просмотра в URL-адресе, то есть в основном 3 способа:

    1. Принесите некоторую магию аякса.

          

      Таким образом, первоначально запрошенная страница и, следовательно, URL-адрес запроса в адресной строке браузера остаются неизменными все время.

    2. Если это применимо (например, для навигации по страницам), сделайте запрос GET и используйте includeViewParams=true . Вы можете использовать и для этого:

        

      Однако у этого есть эксплойт безопасности EL в версиях Mojarra старше 2.1.6. Убедитесь, что вы используете Mojarra 2.1.6 или новее. См. Также номер 2247 .

    3. Управляйте генерации URL-адреса действия самостоятельно. Предоставьте настраиваемый ViewHandler (просто ViewHandlerWrapper ), в котором вы выполняете работу в getActionURL() .

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

      Чтобы запустить его, зарегистрируйте его в faces-config.xml следующим образом:

        com.example.YourCustomViewHandler  

      Это также делает OmniFaces . Он поддерживает дополнительный атрибут includeViewParams который включает все параметры вида в URL-адресе формы:

        

    Обновление : получение параметров представления текущего представления программно (что в основном является вашим вторым вопросом) должно выполняться следующим образом:

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

    Правильно ли, что для решения 1 для работы также нужно было бы включить что-то вроде

      

    внутри ?

    Как описано в https://stackoverflow.com/a/14026995/811046

    Давайте будем гением компьютера.