问题:
- 父 JSP 页面中声明了一个变量,子 JSPF 文件中不显示的声明能直接使用这个变量吗
- 上面的情况如果是子 JSP 又如何
实验
新建一个 servlet 在 request 中传入 name 属性,然后 forward 到 parent.jsp 页面中。parent 页面包含三个子页面,分别是 sub.jspf, sub2.jsp 和 sub3.jsp. 前两个通过 <%@ include file="xxx" %>
引入,sub3.jsp 通过 <jsp:include page="xxx"/>
引入。目录结构如下
1 2 3 4 5 6 7 8 9 10 11 12 13
| . ├── java │ └── com │ └── jzheng │ └── servlet │ └── ParentServlet.java └── webapp ├── WEB-INF │ └── web.xml ├── parent.jsp ├── sub.jspf ├── sub2.jsp └── sub3.jsp
|
代码实现如下
1 2 3 4 5 6 7
| public class ParentServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setAttribute("name", "jack"); getServletContext().getRequestDispatcher("/parent.jsp").forward(req, resp); } }
|
parent.jsp 页面取得 request 中的属性,并重命名为 myname
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body>
<% String myname = (String)request.getAttribute("name"); %>
<hr> <h1> include jspf file </h1> <%@ include file="sub.jspf" %>
<hr> <h1> include jsp file </h1> <%@ include file="sub2.jsp" %>
<hr> <h1> jsp:include jsp file </h1> <jsp:include page="sub3.jsp"/>
</body> </html>
|
sub 页面内容如下
1 2 3 4 5 6 7 8 9 10 11
| <!-- sub.jsp --> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <h2> Name: <%= myname%> <h2/>
<!-- sub2.jsp --> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <h2> Name: <%=myname%> </h2>
<!-- sub3.jsp --> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <h2>Name: ${name}</h2>
|
PS: 这里插入一个语法点,<%= myname%>
这种语法是结合 String myname = (String)request.getAttribute("name");
只有 jsp 中声明的变量可以这么用,其实这种写法有点累赘,可以通过 EL 表示式 ${name}
直接从内置对象中取值。
配置 web.xml
1 2 3 4 5 6 7 8
| <servlet> <servlet-name>ParentServlet</servlet-name> <servlet-class>com.jzheng.servlet.ParentServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>ParentServlet</servlet-name> <url-pattern>/parent</url-pattern> </servlet-mapping>
|
启动服务器访问 /parent
可以看到如下结果, 几种方式都能 work.
深入理解
查看编译生成的 JSP 文件,可以看到 parent.jsp 和 sub3.jsp 被编译成了 java/class, sub.jsp 和 sub2.jsp 没有。原因是 <%@ include file="xxx" %>
会将页面直接整合到父页面中,而 <jsp:include page="xxx"/>
则是通过 request 转发达到这个效果的。查看 parent_jsp.java 文件可以更清晰一点. sub 页面处理部分已表明。所以 <%@ include file="xxx" %>
中直接使用父页面定义的变量是可以,这种做法更像是定义了一写通用脚本做包含。但是这些变量都会爆红,非常的不爽
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| response.setContentType("text/html;charset=UTF-8"); 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("\n"); out.write("\n"); out.write("<html>\n"); out.write("<head>\n"); out.write(" <title>Title</title>\n"); out.write("</head>\n"); out.write("<body>\n"); out.write("\n");
String myname = (String)request.getAttribute("name");
out.write("\n"); out.write("\n"); out.write("<hr>\n"); out.write("<h1> include jspf file </h1>\n"); out.write('\n'); out.write('\n'); out.write("\n"); out.write("<h2> Name: "); out.print( myname); out.write(" <h2/>"); out.write("\n"); out.write("\n"); out.write("<hr>\n"); out.write("<h1> include jsp file </h1>\n"); out.write("\n"); out.write("<h2> Name: "); out.print(myname); out.write(" </h2>\n"); out.write("\n"); out.write("\n"); out.write("<hr>\n"); out.write("<h1> jsp:include jsp file </h1>\n"); org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "sub3.jsp", out, false); out.write("\n"); out.write("\n"); out.write("</body>\n"); out.write("</html>\n");
|