日期:2014-05-16 浏览次数:20390 次
?
在JSP中有两种include操作形式,如下:
<%@ include file=” ”%> (这个等价于<jsp:directive.include page=” ” flush=”true”/>)
?
<jsp:include page=” ” flush=”true”/>
?
两种句法的作用在效果上完全相同。前者是指令元素、后者是行为元素。但在性能和维护上却截然不同。
首先,我们知道WEB容器都是将JSP脚本翻译成servlet文件的,下面我们就通过一个示例文件来进一步了解其区别。
首先创建一个被引用的included.html文件:
?
<b>to beincluded file</b>
?
?在创建一个测试index.jsp文件:
?
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>TEST-JSP</title> </head> <body> <%--这里先后用两种方式对文件进行引用--%> <%@include file="included.html" %> <br/> <jsp:include flush="true" page="included.html"></jsp:include> </body> </html>
?好了,现在进行部署。
?
由于Web容器部署的过程包含将JSP文件翻译成servlet的操作(至于这些翻译的中间文件是否删除则看个web容器的设置了),这里以tomcat6为例。在tomcat6/work/Catalina/localhost的文件夹下可以看到你部署的项目,在项目内org/apache/jsp文件夹中又可以看到你刚刚创建的文index_jsp.class和index_jsp.java,打开index_jsp.java,我们可以看到以下内容(介于web容器翻译的方式有些许不同,这里只是作为参考)。由于文件很长,我只取了其中的_jspService方法。
?
public void _jspService(HttpServletRequest request, HttpServletResponse response) throws java.io.IOException, ServletException { PageContext pageContext = null; HttpSession session = null; ServletContext application = null; ServletConfig config = null; JspWriter out = null; Object page = this; JspWriter _jspx_out = null; PageContext _jspx_page_context = null; try { response.setContentType("text/html"); pageContext = _jspxFactory.getPageContext(this, request, response, null, true, 8192, true); _jspx_page_context = pageContext; application = pageContext.getServletContext(); config = pageContext.getServletConfig(); session = pageContext.getSession(); out = pageContext.getOut(); _jspx_out = out; out.write("<html>\n"); out.write(" <head>\n"); out.write(" <meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n"); out.write(" <title>TEST-JSP</title>\n"); out.write(" </head>\n"); out.write(" <body>\n"); out.write(" "); out.write("\n"); out.write(" "); out.write("<b>to beincluded file</b>"); out.write("\n"); out.write(" <br/>\n"); out.write(" "); org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "included.html", out, true); out.write("\n"); out.write(" </body>\n"); out.write("</html>"); } catch (Throwable t) { if (!(t instanceof SkipPageException)){ out = _jspx_out; if (out != null && out.getBufferSize() != 0) try { out.clearBuffer(); } catch (java.io.IOException e) {} if (_jspx_page_context != null) _jspx_page_context.handlePageException(t); } } finally { _jspxFactory.releasePageContext(_jspx_page_context); } }
?可以看到,jsp文件完全被翻译成了servlet的java代码。现在来看我们刚才执行那两条语句的翻译结果:
?
?? ? ?out.write("<b>to beincluded file</b>");
?? ? ?org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "included.html", out, true);
可以看出
这里就可以得出一个结论:
jsp:include动作元素是在请求期间才得以激活并单独进行操作,而include指令元素则是在翻译阶段就已经处理好,使得以后客户访问页面的速度更快了。
但是不是include指令元素就一定比jsp:clude好呢,让我们来想一下。当被引用的文件被修改时,现在应该怎么处理呢?毫无疑问,采用include指令的页面则必须导致相关的页面全部重新部署,而且问题是我们还不知道到底有那些页面引用该修改的页面;相反,采用jsp:include动作元素的