山下寛人オフィシャルブログ

オイシックス株式会社 執行役員 システム本部長 山下寛人の公式ブログです。

<c:if>の中でcontinueすると無限ループ

ApacheのJSTL1.1.2(2012/12/12の最新)で起こります。

以下のようなJSPが無限ループになります。


<%@ page contentType="text/html; charset=SJIS" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<body>
<%
for (int i = 0; i < 10; i ++) {
request.setAttribute("i", i);
%>
<c:if test="${i < 8}">
<%
if (i == 5) { continue; }
%>
<%=i %>
</c:if>
<%
}
%>
</body>
</html>


はif文になるのでなく、Java上ではdo-whileに

変換されるため中にcontinueがあると無限ループになる

可能性があります。

生成されたJavaコードは以下のようになっています。


org.apache.taglibs.standard.tag.rt.core.IfTag _jspx_th_c_005fif_005f0 = (org.apache.taglibs.standard.tag.rt.core.IfTag) _005fjspx_005ftagPool_005fc_005fif_0026_005ftest.get(org.apache.taglibs.standard.tag.rt.core.IfTag.class);
_jspx_th_c_005fif_005f0.setPageContext(_jspx_page_context);
_jspx_th_c_005fif_005f0.setParent(null);
// /jsplooptest.jsp(9,0) name = test type = boolean reqTime = true required = true fragment = false deferredValue = false expectedTypeName = null deferredMethod = false methodSignature = null
_jspx_th_c_005fif_005f0.setTest(((java.lang.Boolean) org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate("${i < 8}", java.lang.Boolean.class, (javax.servlet.jsp.PageContext)_jspx_page_context, null, false)).booleanValue());
int _jspx_eval_c_005fif_005f0 = _jspx_th_c_005fif_005f0.doStartTag();
if (_jspx_eval_c_005fif_005f0 != javax.servlet.jsp.tagext.Tag.SKIP_BODY) {
do {
out.write('\r');
out.write('\n');

if (i == 5) { continue; }

out.write('\r');
out.write('\n');
out.print(i );
out.write('\r');
out.write('\n');
int evalDoAfterBody = _jspx_th_c_005fif_005f0.doAfterBody();
if (evalDoAfterBody != javax.servlet.jsp.tagext.BodyTag.EVAL_BODY_AGAIN)
break;
} while (true);
}
if (_jspx_th_c_005fif_005f0.doEndTag() == javax.servlet.jsp.tagext.Tag.SKIP_PAGE) {
_005fjspx_005ftagPool_005fc_005fif_0026_005ftest.reuse(_jspx_th_c_005fif_005f0);
return;
}


恐ろしい。

このコードだけ見ると、なんでifだけJSTL

してんだ?と思われるかもしれません。

これは実際に発生したのですが、状況としては

もともとスクリプトレットで作成していたJSP

あって、そこにJSTLを追加したという

ことでした。

ご注意ください。