JSF <ui: include /> где src является динамическим и простые

Я борюсь с проблемой, когда я пытаюсь динамически генерировать страницы, используя JSF 2.1 и Primefaces для своего рода проекта CMS. Моя проблема заключается в том, что я пытаюсь динамически включить страницу, которая находится в базе данных, с помощью пользовательского ResourceResolver (эта часть прекрасно работает). Проблема в том, что я использую параметр запроса, чтобы определить, какую страницу обслуживать (например: http://xxx.xxx.com/context/public/?p=2). Это работает нормально, пока я не захочу использовать Ajax или, более конкретно, Primefaces (в моем случае компонент расписания, где мне нужно использовать actionListeners). Я обнаружил, что мое представление не разрешается при выполнении запроса AJAX, вероятно, из-за того, что это область действия запроса. Ниже немного кода:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:p="http://primefaces.org/ui" 
  xmlns:ui="http://java.sun.com/jsf/facelets">
<ui:composition template="/WEB-INF/view/public/templates/public-template.xhtml">
    <ui:define name="body"> 
        <p:outputPanel autoUpdate="false" rendered="#{empty publicBean.site}">
            <div>No site found!</div>
        </p:outputPanel>

        <p:outputPanel autoUpdate="false" rendered="#{! empty publicBean.page and empty publicBean.page.pageTemplate}">
            <div>No valid page template found!</div>
        </p:outputPanel>

        <ui:include src="#{publicBean.view}" />
    </ui:define>
</ui:composition>
</html>

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

Поэтому я вижу, что мои формы на основе ajax (например, с использованием p: commandButton) не работают, когда я делаю это. Я никогда не вижу действия, выполняемые на моих бобах. Но если я жестко закодирую представление, возвращаемое из "#{publicBean.view}", чтобы оно всегда возвращало одно и то же представление, все работает. Поэтому я предполагаю, что во время вызова ajax publicBean.view, вероятно, возвращает ноль или в моем случае AgoraConstants.CUSTOM_VIEW_NOT_FOUND. Вот код в моем бобе поддержки:

public String getView()
{
     // If this below is uncommented, the form with ajax/primefaces works
    //if ( 1 == 1 )
    //{
    //    return "/X-AGORA-VIEW/districtOfficeCalendarTemplate.xhtml";
    //}
    if ( page != null && page.getPageTemplate() != null )
    {
        return AgoraConstants.CUSTOM_VIEW_PREFIX + page.getPageTemplate().getName() + ".xhtml";
    }
    else if ( site != null && site.getLandingPage() != null && site.getLandingPage().getPageTemplate() != null )
    {
        return AgoraConstants.CUSTOM_VIEW_PREFIX + site.getLandingPage().getPageTemplate().getName()+".xhtml";
    }
    return AgoraConstants.CUSTOM_VIEW_NOT_FOUND;
}

Итак, вот мой вопрос, как я могу сохранить параметр запроса, чтобы я мог работать так, как я хочу, с ajax и простыми лицами? Я мог бы бросить это в сеансе, но тогда, если пользователь открывает сайт в двух вкладках с различными представлениями, вещи могут запутаться и работать неправильно. По сути, как я должен хранить переменные запросов, чтобы я мог убедиться, что getView() возвращает то же самое представление для запросов ajax? Кажется, что должно быть простое решение этой проблемы, но я не вижу никакой помощи, которая будет принята с благодарностью.

** Редактировать **

Я также попытался изменить свой поддерживающий компонент для просмотра области (из запроса), но это, похоже, не помогло (но я не знаю почему). Ниже приведен более подробный код компонента. Я добавил метод init, который вызывается при создании компонента с помощью @PostConstruct.

public void init()
{       
    site = null;
    page = null;

    logger.info("Loading public view...");

    if (  getFacesContext().getExternalContext().getRequestParameterMap().containsKey(AgoraConstants.PUBLIC_PAGE_REQUEST_VAR) )
    {
        logger.info("Restoring Page...");
        long value = parseLong((String)getFacesContext().getExternalContext().getRequestParameterMap().get(AgoraConstants.PUBLIC_PAGE_REQUEST_VAR));
        if ( value >= 0 )
        {
            logger.info("Attempting to restore: {}", value);    
            try
            {
                page = pageService.getItem(value);
                if ( page != null )
                {
                    if ( ! page.isEnabled() )
                    {
                        page = null;
                    }
                }
            }
            catch(Exception e)
            {
                logger.warn("Failed to load site: {}", e.getLocalizedMessage());
            }
        }
    }

    if (  page == null && getFacesContext().getExternalContext().getRequestParameterMap().containsKey(AgoraConstants.PUBLIC_SITE_REQUEST_VAR) )
    {
        logger.info("Restoring Site...");
        long value = parseLong((String)getFacesContext().getExternalContext().getRequestParameterMap().get(AgoraConstants.PUBLIC_SITE_REQUEST_VAR));
        if ( value >= 0 )
        {
            logger.info("Attempting to restore: {}", value);    
            try
            {
                site = siteService.getItem(value);
            }
            catch(Exception e)
            {
                logger.warn("Failed to load site: {}", e.getLocalizedMessage());
            }
        }
    }

    if ( page != null && page.getSite() != null)
    {
        site = page.getSite();
    }

    if ( site == null )
    {
        site = siteService.getDefaultSite();
    }
}

public String getView()
{
//        if ( 1 == 1 )
//        {
//            return "/X-AGORA-VIEW/districtOfficeCalendarTemplate.xhtml";
//        }
    if ( page != null && page.getPageTemplate() != null )
    {
        logger.info("a" + AgoraConstants.CUSTOM_VIEW_PREFIX + page.getPageTemplate().getName() + ".xhtml");
        return AgoraConstants.CUSTOM_VIEW_PREFIX + page.getPageTemplate().getName() + ".xhtml";
    }
    else if ( site != null && site.getLandingPage() != null && site.getLandingPage().getPageTemplate() != null )
    {
        logger.info("b" + AgoraConstants.CUSTOM_VIEW_PREFIX + site.getLandingPage().getPageTemplate().getName()+".xhtml");
        return AgoraConstants.CUSTOM_VIEW_PREFIX + site.getLandingPage().getPageTemplate().getName()+".xhtml";
    }
    logger.info("c");
    return AgoraConstants.CUSTOM_VIEW_NOT_FOUND;
} 

2 ответа

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

В этой ситуации вы должны использовать bean-объект области видимости, но есть проблема при использовании области видимости и динамического интерфейса:include. Вы можете проверить это, например, поставить точку останова в вашем конструкторе, и вы увидите, что bean-компонент создается в каждом запросе. Проблема также существует, если вы используете, например, c:if или c:for.

Другие вопросы по тегам