JavaWeb - 简单探讨 JSP
🔎JSP 是什么
JSP 将 Java 代码和特定变动内容嵌入到静态的页面中,实现以静态页面为模板,动态生成其中的部分内容。JSP 文件在运行时会被其编译器转换成更原始的 Servlet 代码。JSP 编译器可以把 JSP 文件编译成用 Java 代码写的 Servlet,然后再由Java编译器来编译成能快速执行的二进制机器码,也可以直接编译成二进制码。
⁉️JSP 是 Servlet 吗?
JSP 实际上是 Servlet。JSP 的 Java 源文件在 Tomcat 安装目录下work\Catalina\localhost\[项目名称]\org\apache\jsp
:
public final class ch_005fjsp_005f01_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports
{ /* ... */ }
我们写的 JSP 继承自 HttpJspBase?,HttpJspBase 又是 HttpServlet 的子类。下图是截取自 Tomcat 官方文档的类继承关系图:
❓为何可以写 HTML?
在 Servlet 中,我们可以在 doGet 或 doPost 方法中获取 PrintWriter 输出流向前端输出一些 HTML 标签:
@WebServlet(name = "register_servlet", urlPatterns = {"/register.do"})
public class RegisterServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.println("<div>博客地址:<a href='https://www.cnblogs.com/Enziandom/'></a></div>");
}
}
JSP 里头写的 HTML 标签是如何显示到浏览器中的呢?打开 JSP 页面的 Java 源文件,找到_jspService()
方法。可以看到一些输出流语句,JSP 的输出流是 JspWriterImpl:
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write(" <title>Chapter JSP 01</title>\r\n");
out.write("</head>\r\n");
out.write("<body>\r\n");
🎯JSP 语法
JSP 虽然可以嵌入 Java 代码,但也不可能随便就直接写 Java 代码在里面。所以,JSP 提供三个标签专门做这个工作:
标签名 | 描述 | 举例 |
---|---|---|
<%%> | 脚本段 | 声明全局变量、函数 |
<%!%> | JSP声明 | 声明局部变量、写 Java 语句 |
<%=%> | JSP表达式 | 输出内容到页面中 |
这三个标签其实还是挺令人费解的😥,因为 Java 的语句、全局变量、函数声明、表达式、局部变量被三个标签安排得明明白白,对于不熟练的初学者来说,还是很容易用混淆。这个时候就体现出源码的重要性了。每一个标签都用一次,然后打开 JSP 的 Java 源文件看看它们都被编译到了什么位置📍:
<html>
<head>
<title>Chapter JSP 01</title>
</head>
<body>
<%!
private final String outside = "global variable";
private void speak(String msg) {
System.out.println(msg);
}
%>
<%
String msg = "Hello World";
speak(msg);
%>
<%=msg%>
</body>
</html>
1️⃣第一个标签<%!%>
里面的内容:
如上图,我们声明的变量就是全局变量,不是在_jspService()
里面声明的局部变量。而且,函数的声明也是在正确的位置中,这完全都是 Java 的基础语法了。
2️⃣第二个标签<%%>
里面的内容:
上图截取了一部分内容,因为_jspService()
函数的内容太多了,而且前面也说到,输出流语句就是在这个函数内的。<%%>
里面声明变量是局部变量,还有一些 Java 语句。
3️⃣第三个标签<%=%>
里面的内容:
如上图,直接被输出流打印了出去。