Почему JSF сохраняет состояние дерева компонентов? - PullRequest
24 голосов
/ 08 сентября 2011

Похоже, что существует разница между состоянием управляемого компонента и состоянием дерева компонентов.Вы можете контролировать состояние управляемого компонента с помощью аннотаций, таких как @ RequestScoped и @ SessionScoped , но, похоже, у вас нет выбора, сохранять или нет состояние дерева компонентов (хотявы можете выбрать, будет ли он сохранен на сервере или на клиенте.)

Кажется, что состояние дерева компонентов должно быть необходимо только на время одного запроса в качестве временной структуры данных, чтобы помочь обработать запрос.Это должно быть восстановлено с нуля для каждого запроса.В JSF 2.0 частичное сохранение состояния делает ситуацию лучше, потому что сохраняются только данные формы, но я не понимаю, почему полезно иметь даже данные формы из предыдущего запроса.

Если ваше приложение использует только управляемые компоненты области запросатогда особенно бессмысленно сохранять состояние дерева компонентов между запросами.Даже если в вашем приложении есть управляемые bean-компоненты области сеанса, я предполагаю, что управляемые bean-компоненты будут содержать состояние, и дерево компонентов по-прежнему не будет нуждаться в каком-либо состоянии между запросами.

Ответы [ 2 ]

21 голосов
/ 31 октября 2011

В добавление к предыдущему ответу, начиная с JSF 2.0, по умолчанию используется то, что называется partial state saving.

Язык описания представлений по умолчанию в JSF (Facelets) создает целое дерево компонентов из исходного Facelet после каждогозапрашивать и инициализировать компоненты из их соответствующих атрибутов тега.Затем он отмечает состояние.

Каждое последующее изменение состояния затем запоминается как изменение дельты, и именно это состояние фактически сохраняется.Вполне может оказаться, что таких изменений просто нет, и тогда состояние представления будет пустым (из-за ошибки состояние никогда не было действительно пустым, но это было недавно исправлено. Подробнее см. http://java.net/jira/browse/JAVASERVERFACES-2203).)

Итак, большой вопрос в том, что же на самом деле находится в этом состоянии, когда оно непустое?

Как уже отмечал BalusC, это может содержать динамические изменения в дереве компонентов.Эти изменения могут быть инициированы либо из резервных компонентов, либо из статических компонентов.Простым примером компонента, который выполняет это динамическое изменение, является компонент таблицы, который создает дочерние компоненты столбцов на основе фактического количества столбцов в наборе данных.

Другим важным использованием состояния представления является запоминание значений.которые были изменены внутри компонентов, но не были вставлены в модель.Это могут быть такие вещи, как щелчок переключателя в компоненте переключателя, перемещение ползунка в компоненте набора и т. Д.

Одним из конкретных примеров является компонент viewParam, который запоминает параметр запроса (параметр строки запроса для GETили параметр POST без лиц), с которым он был инициализирован.См. Это для получения дополнительной информации об этом: http://arjan -tijms.omnifaces.org / 2011/07 / stateless-vs-stateful-jsf-view.html

Существует такжепрочная связь с компонентами с сохранением состояния, запоминанием состояния пользовательского интерфейса и преобразованием или проверкой, которые не выполняются.В этом случае компоненты пользовательского интерфейса запомнят значения, введенные пользователем, и запомнят, что произошла ошибка преобразования / проверки.

Еще одним использованием состояния является оптимизация.Некоторые компоненты вычисляют значения, которые они считают дорогими, чтобы рассчитать и сохранить их в состоянии просмотра.Например, компоненты UIInput делают это после первого постбэка:

private boolean validateEmptyFields(FacesContext ctx) {

    if (validateEmptyFields == null) {
        ExternalContext extCtx = ctx.getExternalContext();
        String val = extCtx.getInitParameter(VALIDATE_EMPTY_FIELDS_PARAM_NAME);

        if (val == null) {
            val = (String) extCtx.getApplicationMap().get(VALIDATE_EMPTY_FIELDS_PARAM_NAME);
        }
        if (val == null || "auto".equals(val)) {
            validateEmptyFields = isBeansValidationAvailable(ctx);
        } else {
            validateEmptyFields = Boolean.valueOf(val);
        }
    }

    return validateEmptyFields;

}

После этого validateEmptyFields сохраняется в состоянии просмотра, поэтому его не нужно вычислять заново после отправки следующей формы.Улучшение было бы, если бы пользователи могли выбирать между перерасчетом или запоминанием (хорошо известная оптимизация пространства-времени).

Сама концепция состояния - это то, что мешало разработке веб-приложений с момента ее ранней концепции.Каждый хочет иметь взаимодействие, которое по существу является состоянием, но почти никто не хочет с ним справляться или даже думать об этом.

JSF пытается дать здесь ответ, но он явно не совершенен и есть возможности для улучшения.Настаивание JSF на возможности восстановления состояния просмотра (даже пустого состояния просмотра) может быть проблематичным, хотя, как было упомянуто в другом ответе, оно обеспечивает неявную защиту от CSRF.JSF 2.2 получит более явную защиту CSRF (см., Например, http://arjan -tijms.omnifaces.org / p / jsf-22.html # 869 ), поэтому, возможно, мы увидим некоторые изменения здесь в будущем.

Возможность отключения состояния для каждого компонента и простое подключение для восстановления состояния в случае, если среда не может (как в ASP.NET), также может быть полезной.

17 голосов
/ 08 сентября 2011

Поскольку дерево компонентов может быть изменено программно в зависимости от первоначального запроса.Это не обязательно воспроизводится при последующем запросе всякий раз, когда необходимо обработать данные формы.

Кроме того, у меня сложилось впечатление, что вы думаете, что дерево компонентов также содержит значения модели.Это неправда.Он содержит только ссылки (по языку выражения) на значения модели (свойства управляемого компонента).Состояние представления не копирует / не дублирует / не содержит состояние модели.Это просто дерево компонентов UI.Возможно, ваше замешательство основано на этом.Обратите внимание, что термин «данные формы» следует интерпретировать как представленные значения и значения модели.

См. Также:

...