您可能知道,JSP 被 Java EE 容器即时转换为 servlet。在 <% ... %> 块中,out 是生成的 servlet 中生成的 _jspService(或类似)方法中的局部变量。这是一个JspWriter,用于写入页面的输出。
在<%! ... %> 块中,您在生成_jspService(或类似)方法的外部,因此您的静态导入意味着您的out 引用是System.out,即不是应该发送页面输出的地方。
如果您想在 <%! ... %> 块中定义 JSP 中的方法,则必须将 out 传递给它们:
<%!
private void test(JspWriter out) throws IOException {
out.println("<p>test</p>");
}
%>
关于那个 JSP -> servlet 的事情,假设我们有这个 JSP:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Example</title>
</head>
<body>
<%
out.println("The current date/time is " + new java.util.Date());
this.test(out, "Hi, Mom!");
%>
<%!
private void test(JspWriter out, String msg) throws java.io.IOException {
out.println(msg);
}
%>
</body>
</html>
请注意,它有一个<%...%> 块和一个<%! ... %> 块。
Java EE 容器将它变成有点像的东西。请注意我们的 test 方法结束的位置,以及我们的 <%...%> 块中的代码结束的位置(以及我们的原始 JSP 文本/标记):
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class test_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
private void test(JspWriter out, String msg) throws java.io.IOException {
out.println(msg);
}
/* ...lots of setup stuff omitted... */
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("<!doctype html>\n");
out.write("<html>\n");
out.write("<head>\n");
out.write("<meta charset=\"utf-8\">\n");
out.write("<title>Example</title>\n");
out.write("</head>\n");
out.write("<body>\n");
out.println("The current date/time is " + new java.util.Date());
this.test(out, "Hi, Mom!");
out.write("\n");
out.write("</body>\n");
out.write("</html>\n");
} 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);
else log(t.getMessage(), t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}