JSP 是一个过时的东西,不需要太过关心,我们只需要了解基本原理即可。
JSP 想要解决的问题
那假设我们现在有一个 Servlet,用来响应用户的请求,由于想要让每个人在返回的页面上看到自己的用户名,所以我们可能会写这样的代码:
package com.example.demo;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
@WebServlet("/demo3")
public class ServletDemo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = getName();
resp.setCharacterEncoding(StandardCharsets.UTF_8.toString());
resp.setContentType("text/html; charset=UTF-8");
final PrintWriter writer = resp.getWriter();
writer.write("<html><body><h1>欢迎," + name + "</h1></body></html>");
}
public String getName() {
return "假设是通过执行逻辑返回的用户名";
}
}
没什么问题,在静态数据中插入动态数据,我们实现了每个用户得到不同的响应。
但是随着页面越来越复杂,我们不可能在 Java 类中写几百行的 html 字符串代码,那 JSP 就出现了,我们可以在 webapp
文件夹中定义 jsp
文件,然后浏览器直接访问文件即可。
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<title>JSP - Hello World</title>
</head>
<body>
<h1>
<% String name = "假设是通过执行逻辑返回的用户名"; %>
<%= name %>
</h1>
</body>
</html>
JSP 提供了一种能力,可以让我们把 Java 代码和 HTML 标签融合到一起,这样就避免了我们在 Java 类中写过多的 html 代码的问题。
JSP 原理
那么 JSP 是怎么实现的呢?假设我们现在访问了 http://localhost:8080/index.jsp
这个资源,服务器收到请求后,发现是 jsp,就会根据这个 jsp 生成一个 java 文件。
在 IDEA Tomcat 启动的时候,可以看到一个 base 文件夹,同时我们访问一下 jsp 资源的话,会发现在 work
文件夹中能够得到这样的目录资源:
其中 index_jsp.java
文件,它是一个类,继承了 org.apache.jasper.runtime.HttpJspBase
,而 HttpJspBase
这个类,则是继承类 HttpServlet
。
所以 JSP 文件的本质,也是一个 Servlet,所以才能够响应用户的请求。类中的 _jspService
方法,就类似 Servlet 的 service
方法。
所以,JSP 的本质就是,服务器会根据 JSP 文件的内容,生成一个 Servlet,其中 _jspService
方法内部,就会把我们 JSP 文件中写的一些指令,生成对应的 Java 代码。
JSP 脚本
<% %>
中间可以放 Java 代码,然后会被插入到jspService
方法中<%! %>
用来定义成员变量,注意这里定义到变量,是index_jsp
类到成员变量,而不是在jspService
方法中。<%= %>
用来输入内容,输入语句中能接收什么语句,这里就能写什么。
JSP 内置对象
内置对象指的是可以在 <% %>
中直接使用的对象,有了上面的知识,我们就可以明白,所谓内置对象,就是 index_jsp
类中有的一些成员属性,因为我们的 Java 代码就是插入在 service 方法中的,那比如 request
这个变量,我们就可以直接使用了,例如:
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<title>JSP - Hello World</title>
</head>
<body>
<h1>
<% request.getMethod(); %>
<% String name = "假设是通过执行逻辑返回的用户名"; %>
<%= name %>
</h1>
</body>
</html>