Основная политика реализации Liferay для view.jsp и метода render - PullRequest
0 голосов
/ 31 августа 2018

Пожалуйста, скажите мне основную политику реализации Liferay. Я делаю портлет списка обзора, тогда я должен отделить одну функцию, такую ​​как поиск, и другую функцию, такую ​​как функция списка, отображаемую изначально? Если они разделены, хотя это будет отображаться полностью на экране, Я думаю, что реализация полностью отличается в случае ее деления и в случае не деления. Я реализую обе функции в 1 jsp как view.jsp без разделения функций сейчас. Должен ли я сделать этот JSP отдельно, даже если оба отображаются совершенно одинаково? Сейчас самое сложное - это метод рендеринга класса портлета. Я получаю данные для отображения в списке с помощью метода рендеринга, но эти данные не используются для других функций в портлете. Метод рендеринга проходит через любой экран, отображаемый в портлете, не так ли? Итак, я думаю, что я мог бы разделить jsp по поиску и списку и отобразить данные в начальном представлении, вызвав службу в списке jsp, хотя оба отображаются совершенно одинаково. Пожалуйста, скажите мне, как это мыслить?

С уважением.

Привет. Olaf.

Это мой пример источника. View.jsp

<%@ include file="/init.jsp" %>

<portlet:actionURL var="searchURL" name="search"></portlet:actionURL>

<aui:form action="<%=searchURL %>" name="<portlet:namespace />fm">

    <div class="search-form">
        <span class="aui-search-bar">
            <aui:input inlineField="<%= true %>" label="name"
            name="authorName" size="30" title="search" type="text"
            />

            <aui:input inlineField="<%= true %>" label="content"
            name="content" size="1" title="search" type="text"
            />

            <aui:button type="submit" value="search" />
        </span>
    </div>
</aui:form>

<jsp:useBean id="lresult" class="java.util.ArrayList"
    type="java.util.List" scope="request" />

<liferay-ui:search-container>
    <liferay-ui:search-container-results results="<%= lresult %>" />

<liferay-ui:search-container-row
    className="com.liferay.service.model.Results" modelVar="results" indexVar="i">

    <liferay-ui:search-container-column-text property="authorName" name="name" />

    <liferay-ui:search-container-column-text property="rating" name="rating" />

    <liferay-ui:search-container-column-text property="content" name="content" />

    <portlet:renderURL var='detailUrl'>
        <portlet:param name='action' value='detail' />
        <portlet:param name='id' value='<%= results.getId() %>' />
        <portlet:param name="jspPage" value="/detail.jsp" />
    </portlet:renderURL>
    <a href='<%=detailUrl %>}'>detail</a>

</liferay-ui:search-container-row>

<liferay-ui:search-iterator />

</liferay-ui:search-container>

И это porltet Java-источник. ResultsListPortlet.java

public class ResultsListPortlet extends MVCPortlet {

    private String authorName = "%";
    private String content = "%";

    public void detail(ActionRequest request, ActionResponse response) {
        try {
            String id = ParamUtil.getString(request, "id");
            Results result = _resultsLocalService.findBysearchResult(id);

            renderRequest.setAttribute("result", result);
        }
        catch (Exception e) {
        }
    }

    public void search(ActionRequest request, ActionResponse response) {
        try {
            authorName = ParamUtil.getString(request, "authorName");
            content = ParamUtil.getString(request, "content");
        }
        catch (Exception e) {
        }
    }

    @Override
    public void render(RenderRequest renderRequest, RenderResponse renderResponse)
            throws IOException, PortletException {

        try {
            List<Results> results = _resultsLocalService.findBysearchResults(authorName,
                    content, 0, 20, null, false);
            authorName = "%";
            content = "%";

            renderRequest.setAttribute("lresult", results);
        }
        catch (Exception e) {
            throw new PortletException(e);
        }

        super.render(renderRequest, renderResponse);
    }

    @Reference(unbind = "-")
    protected void setResultsService(ResultsLocalService resultsLocalService) {
        _resultsLocalService = resultsLocalService;
    }
    private ResultsLocalService _resultsLocalService;
}

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

1 Ответ

0 голосов
/ 06 сентября 2018

Вы никогда не хотите использовать переменные-члены для хранения значений между фазами действия и рендеринга.

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

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

Обычный способ сделать это - использовать атрибуты запроса. Вы можете установить их в фазе действия и получить их в фазе рендеринга.

Таким образом, вы бы вместо этого имели:

public void search(ActionRequest request, ActionResponse response) {
   try {
      authorName = ParamUtil.getString(request, "authorName");
      content = ParamUtil.getString(request, "content");

      request.setAttribute("authorName", authorName);
      request.setAttribute("content", content);
   } catch (Exception e) {
      // you always want to at least log an exception, even if you plan on ignoring.
   }
}

В методе render () вы можете извлечь эти значения String authorName = GetterUtil.getString(renderRequest.getAttribute("authorName"));, чтобы затем выполнить поиск.

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

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

Ожидается, что обработчик действий выполнит реальную работу, но рендеринг должен просто отрендерить результаты. Идея состоит в том, что если страница обновляется 100 раз, вы не завершаете 100 поисков, а только один начальный поиск со 100 визуализациями с одинаковым набором результатов.

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

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

...