Как сохранить и восстановить вид, когда это необходимо

Моя цель - сохранить размер сессии как можно меньше. (Почему?.. это другая тема). То, что я имею, является слушателем фазы, объявленным в face-config.xml

<lifecycle>
        <phase-listener>mypackage.listener.PhaseListener</phase-listener>   
</lifecycle>

Я хочу сохранить все другие представления, кроме последнего (максимум два), в некотором memcache. Получение карты сеанса:

Map<String, Object> sessionMap = event.getFacesContext().getExternalContext().getSessionMap();

Метод beforePhase(событие PhaseEvent) предоставляет мне доступ ко всем представлениям. Поэтому здесь я могу сохранить все представления в memcache и удалить их из сеанса. Вопрос в том, где в jsf запрашиваются эти представления, которые все еще загружены в браузере, чтобы я мог заполнить это представление, если оно необходимо. Это вообще возможно? Спасибо.

1 ответ

Решение

Чтобы решить суть вашего вопроса, реализуйте ViewHandler в рамках которого вы можете взять под контроль RESTORE_VIEW а также RENDER_RESPONSE фазы / процессы. Вы сохраните вид во время RENDER_RESPONSE и выборочно восстанавливать, во время RESTORE_VIEW фаза. Ваш обработчик представления может выглядеть примерно так

   public class CustomViewHandlerImpl extends ViewHandlerWrapper{

        @Inject ViewStore viewStore; //hypothetical storage for the views. Could be anything, like a ConcurrentHashMap
        ViewHandler wrapped;

        public CustomViewHandlerImpl(ViewHandler toWrap){          
           this.wrapped = toWrap;
        }

        public UIViewRoot restoreView(FacesContext context, String viewId) throws IOException{

            //this assumes you've previously saved the view, using the viewId

            UIViewRoot theView = viewStore.get(viewId);

            if(theView == null){

               theView = getWrapped().restoreView(context, viewId);              
            }

           return theView;       
        } 


      public void renderView(FacesContext context, UIViewRoot viewToRender) throws IOException, FacesException{

          viewStore.put(viewToRender.getId(),viewToRender);

          getWrapped().renderView(context, viewToRender);

      }

   }

Просто подключите свой собственный видоискатель, используя

<view-handler>com.you.customs.CustomViewHandlerImpl</view-handler>

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


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

  1. Просмотры без состояния, новые с JSF-2.2. Параметр представления без сохранения состояния позволяет исключить определенные страницы из механизма сохранения представления JSF, просто указав transient="true" на f:view, Гораздо чище, чем калечить UIViewRoot рукой. Предостережение заключается в том, что представление без состояния не может быть подкреплено областями, которые зависят от сохранения состояния, т.е. @ViewScoped, В представлении без гражданства @ViewScoped боб будет воссоздан для каждого постбэка. Функциональность Ajax также страдает в этом сценарии, потому что сохранение состояния является основой ajax-операций.

  2. Выборочно установите компоненты марки как transient Переходное свойство доступно для всех UIComponents Это означает, что для каждого вида вы можете пометить transient="true" эффективно дает вам те же преимущества, что и 1), но в гораздо меньшем объеме. Без обратной стороны нет ViewScoped

РЕДАКТИРОВАТЬ: По какой-то причине, UIViewRoot#getViewId() не возвращает имя текущего представления (это может быть ошибкой). Кроме того, вы можете использовать

ExternalContext extCtxt = FacesContext.getCurrentInstance().getExternalContext();
String viewName = ((HttpServletRequest)extCtxt.getRequest()).getRequestURI();  //use this id as the key to store your views instead
Другие вопросы по тегам