How to include a JSP inside another JSP - Java @ Desk

Saturday, December 6, 2014

How to include a JSP inside another JSP

How to include a JSP inside another JSP

Generally, the two most common ways of including a JSP inside another JSP are:

1. Using the include directive (Static include)
<%@include file="sub.jsp"%>


2. Using jsp:include (Dynamic include)
<jsp:include page="sub.jsp"/>


It is a widely held misconception that both techniques produce the same results and can be used interchangeably. Even though both work well for static contents, for dynamic contents they are very different.
To understand the difference, let us first see how a JSP works.
All JSPs are translated and compiled to a servlet before they are used. Generally, this happens when the first request comes to the JSP (this can be changed to compile all JSPs at the start up). After this, for all subsequent requests to this JSP, this generated servlet does the functioning of the JSP.
Please note that in the subsequent text, for explanation; we have referred to two JSP files as examples – main.jsp (the main JSP file) and sub.jsp (the included JSP file).

Static Include
The <%@include file="" %> tag will inject the contents of the sub file (sub.jsp) into the JSP containing this tag (main.jsp), as if it were copied and pasted. During the JSP compilation of main.jsp, this file and its included sub.jsp are parsed as a single file, with the same context and constraints, and with the included sub.jsp contents copied and pasted in the place containing this tag. Thus, as you can see, the translated servlet will include all the sub.jsp contents. Once the translation and compilation is complete, the generated servlet will have the entire compiled code of both main.jsp and sub.jsp in it. Therefore, if we change sub.jsp post generating this servlet, the changes will not be reflected in main.jsp till its next compilation.

Dynamic Include
The tag adds the content from the value of the page attribute, to the current page at request time (i.e., every time you make a request to the main JSP file, the included JSP file is compiled). The dynamic include is particularly intended for the dynamic content coming from JSPs. In this case, sub.jsp is not compiled when main.jsp is compiled. When you look into the generated servlet, you can see the following code:

org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "sub.jsp", out, false);


This include tag is a run-time instruction to the JSP engine – rather than copying the entire code into the current page, a method call is made to sub.jsp from main.jsp. Therefore, even if you change the sub.jsp after main.jsp is converted to a servlet, it will reflect the changes, as the sub.jsp is rendered every time a call to main.jsp is made (even without recompilation of the main.jsp). However, in this case, the pagecontext and other variables will be different for sub.jsp. If you want to pass some elements, you can use




Sample code illustrating the difference between static and dynamic include

Sub.jsp

<!DOCTYPE html>
SUB CONTENT
Argument from pageContext = <%= pageContext.getAttribute("PARAM") %>
Main.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
 pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<title>Main JSP</title>
</head>
<body>
<% pageContext.setAttribute("PARAM", "Argument");%>
 <P>MAIN CONTENT</P>
 <P>USING @ include</p>
 <p>
  <%@include file="sub.jsp"%>
 </P>

 <P>USING jsp:include</p>
 <p>
  <jsp:include page="sub.jsp" />
 </p>
</body>
</html>


Output
MAIN CONTENT
USING @ include
SUB CONTENT Argument from pageContext = Argument 
USING jsp:include 
SUB CONTENT Argument from pageContext = null  


In the above example, when we used the @include tag; we got the same value for pagecontext in sub.jsp as that in main.jsp. However, when we used jsp:include tag, we lost the content in the pagecontext variable. This happened because jsp:include translates the sub.jsp with a separate pagecontext during run time.




What to use when

Static include
In most of the cases, you can use the @include tag and it should work fine. It is the fastest mechanism. If your container doesn’t automatically detect changes in the included file, you can force the changes to take effect, by deleting the class file of the main page; so that the next time a request comes, the container will automatically translate both the main file and sub file.

Dynamic include
Use jsp:include tag in the following two cases:
i) If the contents of sub.jsp changes often,
ii) If the page where the sub.jsp needs to be included cannot be decided until the main page is requested.



These are some rare scenarios where you do not remove the main.jsp translated files and only include the sub.jsp to the container.

However, a real scenario where you will need to use the jsp:include tag is for the following error:
_jspService is exceeding the 65535 bytes limit: This is a common issue when dealing with very large JSPs. It happens because most of the JSP code goes into one single method - _jspService - in the translated and compiled servlet; and in java, the maximum size a method can have is 64kb. In such cases, we should invariably use the dynamic include, as it will only have a single line for the sub.jsp (which is a call to JspRuntimeLibrary.include), and the sub.jsp is resolved during run time. This is unlike the static include, which will have all the translated content of sub.jsp in main.jsp during compilation itself.

In addition to these two methods, we also have the following techniques to include one JSP inside another JSP. However, these are not very common.
1. Using the JSTL tag
Works almost like the jsp:include tag, but it’s more powerful and flexible. It can even import the url from outside the web container.
2. Preludes and codas - These can be applied only at the beginnings and ends of pages.
3. Create custom tags
4. Use some framework like "Tiles"

This post is written by Jerin Joseph. He is a freelance writer, loves to explore latest features in Java technology.






No comments:

Post a Comment