Thursday, December 18, 2008

JSP include - Action vs Directive

In one of our web projects, We have a jsp file for creating the main interface of the appication. As development progressed, requirements grew and accordingly our jsp got bigger and bigger. After sometime when we looked back, we could identify some repeating sections (similar layout). Around the same time, we also got a requirement to have a dynamic number of repeating section based on client. With these requirements in mind we started working towards splitting the existing jsp into multiple jsp files and including them either conditionally or always according to the requirements.

So we have two requirements - To conditionally include (and include repeatedly) certain jsp pages and always include other jsp pages, so we came across the classic question of when to use jsp include action vs directive !!

The JSP spec says - action is run-time and directive is compile/translation-time activities. One can expect individual servlet files for each jsp file included using action and all jsps included using directive get merged into the including jsp itself.

Being aware of this information, we divided our huge jsp into multiple small files and gave them an extention jspf (for jsp fragment). Then we used jsp include directive for all the pages that need to be included always and jsp include action for other case, where need to repetitively include certain number of times based on some conditions. When tested this setup, no dynamic behaviour is displayed by the jsp include action and to make the problem more interesting we ended up with only a single servlet at the server-side (tested on both JBOSS and Websphere). We tried various combinations and tried changing everywhere to use only include actions, only include directives and other meaningful combinations and ended up with same result.

We did extensive googling and listed out the key differences between jsp include directive and action as below:

JSP include directive:

1. Affects the process during compile/translation of including JSP and the result is - whole content gets copied into the including JSP.
2. JSP could be completely static (pure HTML) or completely dynamic (pure JSP) or a mix. The dynamic content (scriptlets, expressions etc) is handled properly while the including JSP is compiled into a servlet.
3. As it is straight content copy, any variables declared in the including JSP are available for use.
4. The included JSP need not be valid on its own as it never gets compiled alone, but always as part of the including JSP
5. The file attribute value has to be a static name

JSP include action:

1. Affects the process during run-time/execution of including JSP, which means the including JSP get only the result of its execution (through an explicit call).
2. With include action, we can pass parameters from the including JSP and make the content more dynamic.
3. As the including JSP gets only the result of included JSP, variables declared in the including JSP are not accessible.
4. The included JSP need to be completely valid on its own.
5. The page attribute value could be dynamic (an expression)

We understand all the above points, but still couldn't understand where the problem is ! Finally, we tried renaming all *.jspf files to *.jsp and tested and bingo !! multiple servlets got created as expected for each include action. The undocumented rule is - as long as the included file extention is not jsp, include action works exactly as if it is a directive without throwing any errors. We observed the same behaviour with JBOSS (Tomcat) and Websphere. Hope this saves some effort for others.

No comments: