With the include directive, there is NO difference between you opening your JSP page and pasting in the contents of “Header.jsp”. In other words, it really is just as though you duplicated the code from the header file into your other JSP. Except the Container does it at translation time for you, so that you don’t have to duplicate the code everywhere. You can write all your pages with an include directive, and the Container will go through the trouble of copying the header code into each JSP before translating and compiling the generated servlet.
But <jsp:include> is a completely different story. Rather than copying in the source code from “Header.jsp”, the include standard action inserts the response of “Header.jsp”, at runtime. The key to <jsp:include> is that the Container is creating a RequestDispatcher from the page attribute and applying the include() method. The dispatched/included JSP executes against the same request and response objects, within the same thread.
The include directive inserts the SOURCE of “Header.jsp”, at translation time.
But the <jsp:include /> standard action inserts the RESPONSE of “Header.jsp”, at runtime.
Q: So why wouldn’t you always use <jsp:include>? That way you can guarantee you’ll always have the latest content.
A: Think about it. There’s an extra performance hit with every <jsp:include>. With the directive, on the other hand, the hit happens only once—when ...