我已经创建了一个基本的Jsp示例,当我浏览Jsp自动创建的Servlet文件时。我在 _jspService 方法中看到了PageContext和JspWriter的两个引用。为什么有两个 PageContext 和 JspWriter
的引用 public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
`
答案 0 :(得分:1)
这个问题涉及JSP自定义标记库和标记文件的实现。
非最终变量PageContext
和JspWriter
可能会在运行时更改。这是一个示例JSP
<html><body><%@ taglib uri="http://tomcat.apache.org/example-taglib" prefix="eg"%>
<eg:log>It's <%="TEST"%></eg:log></body></html>
生成Tomcat 7的java代码
1 pageContext = _jspxFactory.getPageContext(this, request, response, null, true, 8192, true);
2 _jspx_page_context = pageContext;
3 application = pageContext.getServletContext();
4 config = pageContext.getServletConfig();
5 session = pageContext.getSession();
6 out = pageContext.getOut();
7 _jspx_out = out;
8 out.write("<html><body>\r\n");
9 // eg:log
10 examples.LogTag _jspx_th_eg_005flog_005f0 = (examples.LogTag) _005fjspx_005ftagPool_005feg_005flog.get(examples.LogTag.class);
11 _jspx_th_eg_005flog_005f0.setPageContext(_jspx_page_context);
12 _jspx_th_eg_005flog_005f0.setParent(null);
13 int _jspx_eval_eg_005flog_005f0 = _jspx_th_eg_005flog_005f0.doStartTag();
14 if (_jspx_eval_eg_005flog_005f0 != javax.servlet.jsp.tagext.Tag.SKIP_BODY) {
15 if (_jspx_eval_eg_005flog_005f0 != javax.servlet.jsp.tagext.Tag.EVAL_BODY_INCLUDE) {
16 out = _jspx_page_context.pushBody();
17 _jspx_th_eg_005flog_005f0.setBodyContent((javax.servlet.jsp.tagext.BodyContent) out);
18 _jspx_th_eg_005flog_005f0.doInitBody();
19 }
20 do {
21 out.write("It's ");
22 out.print("TEST");
23 int evalDoAfterBody = _jspx_th_eg_005flog_005f0.doAfterBody();
24 if (evalDoAfterBody != javax.servlet.jsp.tagext.BodyTag.EVAL_BODY_AGAIN)
25 break;
26 } while (true);
27 if (_jspx_eval_eg_005flog_005f0 != javax.servlet.jsp.tagext.Tag.EVAL_BODY_INCLUDE) {
28 out = _jspx_page_context.popBody();
29 }
30 }
在第16行,一旦程序执行_jspx_page_context.pushBody()
。
返回一个新的JSPWriter
。
它用于捕获正文的输出,因此数据不会直接写入response outputStream
。
LogTag.doAfterBody()
可以捕获输出并处理它。