JSP Tutorials - Herong's Tutorial Examples - v5.11, by Herong Yang
Example - Calculating Prime Numbers
This section provides a tutorial example to calculate prime numbers using a JSTL Core library c:forEach tag. But example works. But it is not perfect, because it has no break statement.
As my second JSTL core example, JstlPrimeNumbers.jsp, is to calculate if a given number is prime number or not.
<?xml version="1.0"?> <jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:c="http://java.sun.com/jsp/jstl/core" version="2.1"> <!-- JstlPrimeNumbers.jspx - It doesn't work, can not change the index - Copyright (c) 2006 HerongYang.com. All Rights Reserved. --> <jsp:directive.page contentType="text/html"/> <html><body> <p>Checking prime numbers:</p> <c:set var="upperLimit" value="${20}"/> <c:forEach var="i" begin="${3}" end="${upperLimit}"> <c:set var="isPrime" value="${true}"/> <c:forEach var="j" begin="${2}" end="${i-1}"> <c:if test="${i%j == 0}"> <c:set var="isPrime" value="${false}"/> <!-- We should break the loop here --> </c:if> </c:forEach> <c:choose> <c:when test="${isPrime}"> <c:out value="${i} is a prime number."/><br/> </c:when> <c:otherwise> <c:out value="${i} is a not prime number."/><br/> </c:otherwise> </c:choose> </c:forEach> </body></html> </jsp:root>
I am not showing you the output here. But the output is correct. Trust me. As you can see in the source code, I am not breaking the loop on "j" when "i" has already been approved as a non-prime number, because I don't know how.
One of the emails I received after publishing the above notes suggests me to insert a Java break statement through a scriptlet to break the "forEach" tag. To try this idea, I revised my JSP page to JstlPrimeNumbersRevised.jsp:
<?xml version="1.0"?> <jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:c="http://java.sun.com/jsp/jstl/core" version="2.1"> <!-- JstlPrimeNumbersRevised.jsp - Compilation error - Copyright (c) 2006 HerongYang.com. All Rights Reserved. --> <jsp:directive.page contentType="text/html"/> <html><body> <p>Checking prime numbers:</p> <c:set var="upperLimit" value="${20}"/> <c:forEach var="i" begin="${3}" end="${upperLimit}"> <c:set var="isPrime" value="${true}"/> <c:forEach var="j" begin="${2}" end="${i-1}"> <c:if test="${i%j == 0}"> <c:set var="isPrime" value="${false}"/> <jsp:scriptlet>break;</jsp:scriptlet> </c:if> </c:forEach> <c:choose> <c:when test="${isPrime}"> <c:out value="${i} is a prime number."/><br/> </c:when> <c:otherwise> <c:out value="${i} is a not prime number."/><br/> </c:otherwise> </c:choose> </c:forEach> </body></html> </jsp:root>
If the scriptlet statement can merge with the JSTL tags nicely, the logic will work. However if you view this page on Tomcat, you will get a compilation error saying that there is an unreachable statement:
HTTP Status 500 - Unable to compile class for JSP: type Exception report message Unable to compile class for JSP: description The server encountered an internal error that prevented it from fulfilling this request. exception org.apache.jasper.JasperException: Unable to compile class for JSP: An error occurred at line: 8 in the jsp file: /JstlPrimeNumbersRevised.jspx Unreachable code 5: - Copyright () 2012, HerongYang.com, All Rights Reserved. 6: --> 7: <jsp:directive.page contentType="text/html"/> 8: <html><body> 9: <p>Checking prime numbers:</p> 10: <c:set var="upperLimit" value="${20}"/> 11: <c:forEach var="i" begin="${3}" end="${upperLimit}"> Stacktrace: org.apache.jasper.compiler.DefaultErrorHandler.javacError() org.apache.jasper.compiler.ErrorDispatcher.javacError() org.apache.jasper.compiler.JDTCompiler.generateClass() org.apache.jasper.compiler.Compiler.compile() org.apache.jasper.compiler.Compiler.compile() org.apache.jasper.compiler.Compiler.compile() org.apache.jasper.JspCompilationContext.compile() org.apache.jasper.servlet.JspServletWrapper.service() org.apache.jasper.servlet.JspServlet.serviceJspFile() org.apache.jasper.servlet.JspServlet.service() javax.servlet.http.HttpServlet.service() ...
If you open the converted Java class file of the JSP page, JstlPrimeNumbersRevised_jspx.java, you will see:
/* * Generated by the Jasper component of Apache Tomcat * Version: Apache Tomcat/9.0.12 ... */ ... // c:forEach org.apache.taglibs.standard.tag.rt.core.ForEachTag _jspx_th_c_005ff... _jspx_th_c_005fforEach_005f0.setPageContext(_jspx_page_context); _jspx_th_c_005fforEach_005f0.setParent(null); // /JstlPrimeNumbersRevised.jspx(11,53) name = end type = int reqTi... _jspx_th_c_005fforEach_005f0.setEnd(((java.lang.Integer) org.apache... // /JstlPrimeNumbersRevised.jspx(11,53) name = begin type = int req... _jspx_th_c_005fforEach_005f0.setBegin(((java.lang.Integer) org.apac... // /JstlPrimeNumbersRevised.jspx(11,53) name = var type = java.lang... _jspx_th_c_005fforEach_005f0.setVar("i"); int[] _jspx_push_body_count_c_005fforEach_005f0 = new int[] { 0 }; try { int _jspx_eval_c_005fforEach_005f0 = _jspx_th_c_005fforEach_005f0... if (_jspx_eval_c_005fforEach_005f0 != javax.servlet.jsp.tagext.Ta... do { if (_jspx_meth_c_005fset_005f1(_jspx_th_c_005fforEach_005f0, ... return; // c:forEach org.apache.taglibs.standard.tag.rt.core.ForEachTag _jspx_th_c... _jspx_th_c_005fforEach_005f1.setPageContext(_jspx_page_contex... _jspx_th_c_005fforEach_005f1.setParent((javax.servlet.jsp.tag... // /JstlPrimeNumbersRevised.jspx(13,47) name = end type = int... _jspx_th_c_005fforEach_005f1.setEnd(((java.lang.Integer) org.... // /JstlPrimeNumbersRevised.jspx(13,47) name = begin type = i... _jspx_th_c_005fforEach_005f1.setBegin(((java.lang.Integer) or... // /JstlPrimeNumbersRevised.jspx(13,47) name = var type = jav... _jspx_th_c_005fforEach_005f1.setVar("j"); int[] _jspx_push_body_count_c_005fforEach_005f1 = new int[] {... try { int _jspx_eval_c_005fforEach_005f1 = _jspx_th_c_005fforEach... if (_jspx_eval_c_005fforEach_005f1 != javax.servlet.jsp.tag... do { // c:if org.apache.taglibs.standard.tag.rt.core.IfTag _jspx_th_... _jspx_th_c_005fif_005f0.setPageContext(_jspx_page_conte... _jspx_th_c_005fif_005f0.setParent((javax.servlet.jsp.ta... // /JstlPrimeNumbersRevised.jspx(14,28) name = test typ... _jspx_th_c_005fif_005f0.setTest(((java.lang.Boolean) or... int _jspx_eval_c_005fif_005f0 = _jspx_th_c_005fif_005f0... if (_jspx_eval_c_005fif_005f0 != javax.servlet.jsp.tage... do { if (_jspx_meth_c_005fset_005f2(_jspx_th_c_005fif_00... return; break; int evalDoAfterBody = _jspx_th_c_005fif_005f0.doAft... if (evalDoAfterBody != javax.servlet.jsp.tagext.Bod... break; } while (true); } if (_jspx_th_c_005fif_005f0.doEndTag() == javax.servlet... _005fjspx_005ftagPool_005fc_005fif_0026_005ftest.reus... return; } _005fjspx_005ftagPool_005fc_005fif_0026_005ftest.reuse(... int evalDoAfterBody = _jspx_th_c_005fforEach_005f1.doAf... if (evalDoAfterBody != javax.servlet.jsp.tagext.BodyTag... break; } while (true); } if (_jspx_th_c_005fforEach_005f1.doEndTag() == javax.servle... return; } } catch (java.lang.Throwable _jspx_exception) { while (_jspx_push_body_count_c_005fforEach_005f1[0]-- > 0) out = _jspx_page_context.popBody(); _jspx_th_c_005fforEach_005f1.doCatch(_jspx_exception); } finally { _jspx_th_c_005fforEach_005f1.doFinally(); _005fjspx_005ftagPool_005fc_005fforEach_0026_005fvar_005fen... } if (_jspx_meth_c_005fchoose_005f0(_jspx_th_c_005fforEach_005f... return; int evalDoAfterBody = _jspx_th_c_005fforEach_005f0.doAfterBod... if (evalDoAfterBody != javax.servlet.jsp.tagext.BodyTag.EVAL_... break; } while (true); } ...
The reason for the compilation error is clear. The c:forEach tag has been converted to a Java "while" loop - no surprise. However the c:if tag is also converted to a Java "while" loop - big surprise. The break statement provided by the scriptlet is placed in the middle of a while loop without if condition, and it causes the "code not reachable" compilation error.
So there is still no easy way to break a c:forEach tag.
Table of Contents
JSP (JavaServer Pages) Overview
Tomcat Installation on Windows Systems
Syntax of JSP Pages and JSP Documents
JavaBean Objects and "useBean" Action Elements
Managing HTTP Response Header Lines
Non-ASCII Characters Support in JSP Pages
Overview of JSTL (JSP Standard Tag Libraries)
c:out Action Tag with EL Expressions
Example - Dumping EL Implicit Objects
►Example - Calculating Prime Numbers
Multiple Tags Working Together
Using Tomcat on CentOS Systems
Connecting to SQL Server from Servlet