Java 您能使JSP在未声明的变量上崩溃吗?
我们注意到JSP中未声明的变量可能会导致非常糟糕的性能 查看以下示例代码:Java 您能使JSP在未声明的变量上崩溃吗?,java,jsp,Java,Jsp,我们注意到JSP中未声明的变量可能会导致非常糟糕的性能 查看以下示例代码: <c:if test="..."> <c:set var="isSaleCategory" value="true"/> </c:if> <c:forEach items="${ARTICLES}" var="article" varStatus="status"> <c:if test="${not empty articlePrice &
<c:if test="...">
<c:set var="isSaleCategory" value="true"/>
</c:if>
<c:forEach items="${ARTICLES}" var="article" varStatus="status">
<c:if test="${not empty articlePrice && (!isSaleCategory)}">
代码处理和返回结果花费了5-6秒
如果我们首先初始化变量,执行时间将下降到几毫秒:
<c:set var="isSaleCategory" value="false"/>
<c:if test="...">
<c:set var="isSaleCategory" value="true"/>
</c:if>
<c:forEach items="${ARTICLES}" var="article" varStatus="status">
<c:if test="${not empty articlePrice && (!isSaleCategory)}">
现在,我们不介意添加这些代码来初始化变量,但棘手的部分是找到它们。。。在没有循环的页面上,我们不会看到第二次+响应时间,但在重载情况下,这当然会增加不必要的负载
当JSP遇到上述未初始化的变量时,有没有办法使其处理失败?当访问未声明的变量时,它的速度很慢的问题是,解析程序会深入挖掘以尝试找到变量 看 尝试大量未声明的变量时会抛出许多ClassNotFoundException,这需要花费大量时间 解决这个问题的一种方法是编写一个自定义ELResolver,如果在页面范围中找不到值为null的变量,它只需将该变量作为已解析变量,这样就可以防止框架进一步挖掘
private static class NullOnMissingVariableELResolver extends ELResolver
{
/** {@inhericDoc} */
@Override
public Object getValue(ELContext context, Object base, Object property)
{
if (base == null && property != null)
{
String key = property.toString();
PageContext page = (PageContext) context.getContext(JspContext.class);
Object result = page.findAttribute(key);
if (result == null)
{
context.setPropertyResolved(true);
}
}
return null;
}
当然,这需要注意,如果您有使用这些特殊类查找的模板,它们将无法工作 我发现了关于这个问题的更多信息,它似乎出现在Tomcat 8中: 另一种解决方案是在变量前面加上作用域,而不是:
${isSaleCategory}
使用
虽然这意味着对jsp文件进行了大量更改,但是Marcus与客户ELResolver的回答很好地发现了这些情况。没有NPE吗?看起来更像是第二次测试中的错误处理,其中由于第一次测试失败而无法设置
isSaleContegory
。如果您想在第二个测试中添加NullPointer检查作为OR条件,该怎么办?(isSaleCategory为null | | |!isSaleCategory)
您的文章集有多大?似乎奇怪的是,变量强制应该如此昂贵。@Antoniossss JSP非常宽容(这是本例中的核心问题),对于这些场景,不要抛出任何异常。很好的建议!在开发模式下,我们可以将ELResolver设置为引发异常并修复未设置的变量。找到了根本原因:
${requestScope.isSaleCategory}