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 中其他用户(可能是管理员)的呈现调用之间发生变化,因此您的结果可能会发生变化,这违反了规范的精神。
也就是说,我认为也可以争辩说,在您的情况下应该相同的状态是搜索条件,如果搜索结果被其他用户更改,则更新后的结果是预期的结果。
请告诉我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 中其他用户(可能是管理员)的呈现调用之间发生变化,因此您的结果可能会发生变化,这违反了规范的精神。
也就是说,我认为也可以争辩说,在您的情况下应该相同的状态是搜索条件,如果搜索结果被其他用户更改,则更新后的结果是预期的结果。