当我浏览由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定制标记库和标记文件的实现。
非最终变量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()
可以获取捕获的输出并进行处理。