view.jsp的基本Liferay实现策略和render方法

The basic Liferay implementation policy of view.jsp and render method

请告诉我Liferay 的基本实施政策。 我正在制作评论列表的 porlet,那么我是否应该将一个功能(如搜索)和另一个功能(如最初显示的列表功能)分开? 如果它们被分开,虽然它会完全相同地显示在屏幕上, 我认为在划分和不划分的情况下实现是完全不同的。 我在 1 jsp 作为 view.jsp 实现了两个功能,现在没有分离功能。 我是否应该单独制作此 jsp,即使两者显示完全相同? 现在最头疼的就是portlet的render方法class。 我正在使用 render 方法获取要显示在列表中的数据,但此数据未用于 portlet 中的其他功能。 render 方法通过 portlet 中显示的任何屏幕,不是吗? 因此,我认为我可以通过搜索和列表分开 jsp,并通过调用列表 jsp 中的服务在初始视图中显示数据,尽管两者显示完全相同。 请告诉我这样的基本思路?

此致。

你好。奥拉夫

这是我的示例源。 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;
}

render方法中renderRequest中设置的数据lresults用于搜索和列表功能。 但是,它不用于其他功能,例如显示详细数据的详细功能和注册数据的注册功能。 这个lresults对于详细功能或注册功能来说不是必须的,我认为这样的实现是不好的。 所以请告诉我如何正确或正确地更改实现。

您永远不想使用成员变量来保存动作和渲染阶段之间的值。

将调用一个 portlet class 来为所有用户的请求提供服务,因此这些成员变量将不断更改,您的结果将不是您想要的。

当然它在本地对你有效,因为你没有用户针对你的开发系统进行测试,只有你在测试,所以成员字段是安全的。

执行此操作的常规方法是使用请求属性。您可以在操作阶段设置它们并在渲染阶段检索它们。

所以你会拥有:

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"));然后完成搜索。

这使得值不会存储在成员字段中,并且无论有多少用户访问 portlet 都将起作用。

我认为值得提出一个问题,是在渲染阶段进行实际搜索还是应该在动作阶段完成搜索。

期望动作处理程序执行实际工作,但渲染应该只渲染结果。这个想法是,如果一个页面被刷新 100 次,您就不会完成 100 次搜索,而只会完成一次具有 100 次呈现相同结果集的初始搜索。

不是操作请求目标的 portlet 应该重新呈现与先前呈现相同的结果;渲染不应该有副作用。由于您的搜索结果可能会在其他 portlet 中其他用户(可能是管理员)的呈现调用之间发生变化,因此您的结果可能会发生变化,这违反了规范的精神。

也就是说,我认为也可以争辩说,在您的情况下应该相同的状态是搜索条件,如果搜索结果被其他用户更改,则更新后的结果是预期的结果。