Локальный экземпляр tc Server 3.1 завершает bean-компоненты @ViewScoped и @SessionScoped

ОБНОВЛЕНИЕ:

Жизненные циклы любых компонентов @ViewScoped и @SessionScoped не соответствуют ожидаемым. То есть они заканчиваются раньше, чем должны. Например, когда выполняется обратная передача ajax, когда метод возвращает void, ни @ViewScoped, ни @SessionScoped bean-компоненты не должны заканчиваться, но они заканчиваются.

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

Я оставляю оригинал на случай, если кто-то столкнется с проблемой аналогично.

Оригинал:

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

@ManagedBean
@ViewScoped
public class FundsXmlTreeBuilder implements Serializable {

    private TreeNode root;

    public FundsXmlTreeBuilder() throws SAXException, IOException, ParserConfigurationException {
        root = new DefaultTreeNode("Root", null);
        buildTree();
    }

    public void buildTree() throws SAXException, IOException, ParserConfigurationException {
        //reads xml file and adds TreeNodes
    }
}

Существует еще один bean-компонент RequestScoped, у которого есть метод, обрабатывающий ajax-событие узла дерева, выбранного в методе onNodeSelect. Он в основном определяет, как будет отображаться другая часть страницы.

@ManagedBean
@RequestScoped
public class FundsXmlDisplay implements Serializable{

    private Fund fund;
    private FundFamily fundFamily;
    private FocusedPortfolioModel model;

    public TreeNode selectedRoot;

    public FundsXmlDisplay() {
        fund = null;
        fundFamily = null;
        model = null;

        selectedRoot = null;
    }

    public void onNodeSelect(NodeSelectEvent event) {
        Object data = event.getTreeNode().getData();

        fund = null;
        fundFamily = null;
        model = null;
        if (data instanceof Fund) {
            fund = (Fund) data;
        } else if (data instanceof FundFamily) {
            fundFamily = (FundFamily) data;
        } else if (data instanceof FocusedPortfolioModel) {
            model = (FocusedPortfolioModel) data;
            model.createPieModel();
        }
    }
}

Вот основные части разметки.

<h:body>

    <h:form styleClass="form" id="form1">
        *** For Home Office Use Only
        <br />

        <p:layout id="xmlArea"
            style="min-width:400px;min-height:600px;width:95%;">
            <p:layoutUnit id="xmlTree" position="west" resizable="false"
                closable="false" scrollable="true" size="25%" minSize="40"
                maxSize="400" style="padding:.25em;" header="Funds XML Elements">
                    <p:tree value="#{fundsXmlTreeBuilder.root}" var="node"
                        dynamic="false" selectionMode="single">
                        <p:ajax event="select" update=":form1:xmlDisplay"
                            listener="#{fundsXmlDisplay.onNodeSelect}" />
                        <p:treeNode>
                            <h:outputText value="#{node}" style="font-size:small" />
                        </p:treeNode>
                    </p:tree>
            </p:layoutUnit>

            <p:layoutUnit position="center" header="Element Detail" size="75%">
                <p:scrollPanel id="xmlDisplay" mode="native"
                    style="height:100%;">
                    ...
                </p:scrollPanel>
            </p:layoutUnit>
        </p:layout>
    </h:form>

</h:body>

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

В области xmlDisplay довольно много отображаемых атрибутов. Не уверен, что это актуально. Я понимаю, что представление живет, когда метод действия возвращает null или void, но я не думаю, что используемые визуализированные методы считаются «методами действия».

Что также интересно, если я изменю FundsXmlTreebuilder на SessionScoped, он будет воссоздан и после выбора узла, что действительно поставило меня в тупик.

Надеюсь, все понятно и информации достаточно. Спасибо!


person cfreih    schedule 05.01.2016    source источник
comment
рассматриваемый bean-компонент, который воссоздается, — это FundsXmlDisplay, верно?   -  person Mahendran Ayyarsamy Kandiar    schedule 05.01.2016
comment
Должен был указать. FundsXmlTreeBuilder - это тот, который воссоздается, когда я этого не ожидаю (после события ajax, но до выполнения прослушивателя). Я отредактирую вопрос, чтобы сделать его более понятным.   -  person cfreih    schedule 05.01.2016
comment
вы можете заменить layout и layoutUnits на старые простые div и css и посмотреть, что произойдет?   -  person Mahendran Ayyarsamy Kandiar    schedule 06.01.2016
comment
Форма вокруг макета — не лучший дизайн. И ** не выполняйте никаких действий в конструкторе, используйте @PostConstruct аннотированный метод. Ищите дубликат в SO, он существует   -  person Kukeltje    schedule 20.01.2016
comment
Хм, дубликат не совсем правильный… нужно найти другой.   -  person Kukeltje    schedule 20.01.2016
comment
Требования немного изменились, поэтому я удалил layoutUnits. Не могли бы вы объяснить, почему это такой плохой дизайн? Я пытался использовать @PostConstruct, но этот метод никогда не вызывался. Я чувствую, что это может быть связано с тем, что бобы неожиданно воссоздаются локально.   -  person cfreih    schedule 20.01.2016
comment
Большая вероятность случайного получения вложенных форм. Прочитайте о «форме бога» здесь (2-й маркер): title="commandlink commandbutton ajax метод слушателя действия bean-компонента не вызван"> stackoverflow.com/questions/2118656/   -  person Kukeltje    schedule 21.01.2016


Ответы (1)


В web.xml необходимо закомментировать тег <secure>. Так выглядит соответствующий раздел:

<session-config>
    <session-timeout>60</session-timeout>
    <cookie-config>
        <http-only>true</http-only>
<!--        <secure>true</secure> --> <-- Not be set locally -->
    </cookie-config>
    <tracking-mode>COOKIE</tracking-mode>
</session-config>

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

Здесь я нашел объяснение. Товарищ по команде обнаружил исправление.

person cfreih    schedule 21.01.2016