当我浏览由Jsp自动创建的Servlet文件时,我已经创建了一个基本的Jsp示例。我已经在 _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;

`

最佳答案

这个问题涉及JSP定制标记库和标记文件的实现。
非最终变量PageContextJspWriter在运行时可能会更改。这是一个示例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 outputStreamLogTag.doAfterBody()可以获取捕获的输出并进行处理。

09-11 18:53