Java 如何在Struts 2中访问OGNL跟踪评估?
我被告知优化一个web应用程序。为此,我使用 我注意到大部分响应时间都花在了表示层上。特别是,当代码构建HTML代码时 深入研究这个瓶颈,我发现代码处理了很多OGNL类/方法(近50%的调用) 我通过删除一些不必要的OGNL语句对JSP代码进行了调优(详见下文)。我设法跑了200米。然而,代码在这个瓶颈上的平均花费仍然超过2000毫秒。总体响应时间约为3000毫秒 报告说: 从OGNL 2.5.0开始,OgnlContext对象可以自动跟踪表达式的计算。(…)您可以通过OgnlContext的lastEvaluation属性访问上次评估 既然我使用的是Struts 2.3.15.1(OGNL v3.0.6),那么我如何从JSP文件或Action类访问该属性或调用Java 如何在Struts 2中访问OGNL跟踪评估?,java,jsp,struts2,struts,ognl,Java,Jsp,Struts2,Struts,Ognl,我被告知优化一个web应用程序。为此,我使用 我注意到大部分响应时间都花在了表示层上。特别是,当代码构建HTML代码时 深入研究这个瓶颈,我发现代码处理了很多OGNL类/方法(近50%的调用) 我通过删除一些不必要的OGNL语句对JSP代码进行了调优(详见下文)。我设法跑了200米。然而,代码在这个瓶颈上的平均花费仍然超过2000毫秒。总体响应时间约为3000毫秒 报告说: 从OGNL 2.5.0开始,OgnlContext对象可以自动跟踪表达式的计算。(…)您可以通过OgnlContext的l
OgnlContext
的getLastEvaluation
JSP文件
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix ="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
<head>
<title><s:text name="domain.domain0.title"/></title>
<script type="text/javascript" src="<s:url value='/js/domain/domain0.js'/>"></script>
<script type="text/javascript" src="<s:url value='/js/core/html.js'/>"></script>
</head>
<body>
<div style="width:100%;color:green;font-weight: bold;text-align:center">
<s:text name="domain.domain0.information"/>
</div>
<div class="content selectFen">
<s:set var="noAnchor">false</s:set>
<s:iterator value="artefactList" status="numRow">
<s:if test="court == nomenclatureCritere && #noAnchor!=true">
<s:set var="noAnchor">true</s:set>
<a id="NomencAnchor" href="#NomencAnchor" style="visibility:hidden;"></a>
</s:if>
<s:set var="isOpen" value="nomenclatureCritere.startsWith(court) || ligProd != '80'"/>
<div class="parcoursNomenc">
<table onmouseover='this.style.backgroundColor="gainsboro"' onmouseout='this.style.backgroundColor=""' style="width: 100%;font-weight:bolder">
<tbody>
<tr>
<s:url var="childNomenUrl" action="ajaxPopupNomenChild" escapeAmp="false">
<s:param name="dateCritere" value="dateCritere"/>
<s:param name="sidNomenclaturePere" value="sidArtNomenc"/>
</s:url>
<s:if test="#isOpen">
<s:if test="#numRow.last">
<td onclick="noeudPlusMoins(this);loadChild('<s:property value="childNomenUrl" />', 'divParcours<s:property value="sidArtNomenc"/>')" class="open_last"> </td>
</s:if>
<s:else>
<td onclick="noeudPlusMoins(this);loadChild('<s:property value="childNomenUrl" />', 'divParcours<s:property value="sidArtNomenc"/>')" class="open"> </td>
</s:else>
</s:if>
<s:else>
<s:if test="#numRow.last">
<td onclick="noeudPlusMoins(this);loadChild('<s:property value="childNomenUrl" />', 'divParcours<s:property value="sidArtNomenc"/>')" class="closed_last"> </td>
</s:if>
<s:else>
<td onclick="noeudPlusMoins(this);loadChild('<s:property value="childNomenUrl" />', 'divParcours<s:property value="sidArtNomenc"/>')" class="closed"> </td>
</s:else>
</s:else>
<td style="vertical-align: top; width: 8.5em; padding-top: 5px;">
<s:text name="domain.domain0.label"/> <s:property value="court"/>
</td>
<td class="description">
<s:property value="description"/>
</td>
</tr>
</tbody>
</table>
<div id="divParcours<s:property value="sidArtNomenc"/>" class="<s:if test="numRow.last">subtree_last</s:if><s:else>subtree</s:else>" >
<s:if test="#isOpen">
<s:action name="popupNomenExist" executeResult="true">
<s:param name="dateCritere" value="dateCritere"/>
<s:param name="nomenclatureCritere" value="nomenclatureCritere"/>
</s:action>
<s:action name="ajaxPopupNomenChild" executeResult="true">
<s:param name="dateCritere" value="dateCritere"/>
<s:param name="sidNomenclaturePere" value="sidArtNomenc"/>
</s:action>
</s:if>
</div>
</div>
</s:iterator>
</div>
</body>
</html>
假的
真的
您可以像
有关如何跟踪评估的说明,请参见您在本节中链接的文档
您还可以在实例化上下文以启用此功能之前设置系统属性
ognl.traceEvaluations
。查看JSP代码,很明显,罪魁祸首是
标记:
在每次迭代中调用两个操作。。。根据迭代的行数,这可能会成为一个严重的问题
我会尝试重构该部分;瓶颈的很大一部分在于解释标记、调用操作、通过拦截器堆栈等的机制
如果您可以生成相同的输出,从而最小化对操作的调用,那么瓶颈将显著减少。
注意:一个非常小的优化是更改S:if中布尔值和字符串比较的顺序,以利用短路(布尔值比较更快):
编辑
没有
s:action
它工作得更好,但是页面需要它们,我不知道如何替换它们
更清楚地说,应该采取行动
- 执行一个(或几个)逻辑动作李>
- 永远不要用作帮助器类
popupNomenExist
时,您唯一的需求就是调用服务器,做一些事情,并接收结果以将其注入JSP
有几种方法可以得到这样的结果,而采取行动可能是最糟糕的(就表现而言,由于上面列出的原因)
您可以从popupNomenExist
操作的execute()
方法获取代码,并且:
此外,我们无法争论popupNomenExist的
execute()
方法中到底执行了什么,但我想它可能会被重构,以防止执行每个迭代所共有的部分逻辑,将它们分组,并在迭代之前作为一种缓存执行。2000ms?您能展示一个示例JSP吗?还考虑升级到至少2.3.153由于安全性reasons@AndreaLigios我已将JSP文件内容添加到我的问题中。ServletContextListener是否适合初始化系统属性?是的,您可以在应用程序启动时执行此操作,请注意,您也可以在DispatcherListener
中执行此操作。关于JSP还有一件事:如果您想要更好的性能,请去掉s:action
标记。我可以用什么来代替s:action
标记?如果我必须自己生成完整的url,他们的执行工作似乎相当困难。请使用操作属性。@Stephan他们是对的,应该不惜一切代价避免使用s:action标记。每次使用该标记时,就好像您从url(包括拦截器)调用了该操作一样,在迭代器中逐行执行此操作非常昂贵#noAnchor比快#noAnchor=true
?否。我的意思是,由于两个表达式(布尔=布尔和对象=对象)位于and中,并且由于短路,如果第一个表达式为false,则不会计算第二个表达式,将最快的表达式作为第一个wil
OgnlContext context = (OgnlContext) ActionContext.getContext().getValueStack().getContext();
context.setTraceEvaluations(true);
Evaluation evaluation = context.getLastEvaluation();