JSP的根本还是Servlet
在调用JSP文件时,会进行如下四步:
1. Http服务器将JSP编辑并生成一个Servlet接口实现类(.java程序)
2. Http服务器编译Servlet接口实现类,生成class文件
3. Http服务器创建此class的实例对象
4. Http服务通过此实例对象,调用其_jspService方法实现功能
JSP详解
先写一个jsp文件,名为one.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Hello World!
<%
int num1=100;
int num2=200;
%>
<%="num1的值为"+num1%>
<%="num2的值为"+num2%>
<%System.out.println(config.getServletContext().getAttribute("javax.servlet.context.tempdir").toString());%>
把网站托管给Tomcat后,访问此one.jsp,可以看到打印出来的文件夹地址:
C:\\Users\\[电脑用户名]\\AppData\\Local\\JetBrains\\[idea版本号]\\tomcat\\[工程名]\\work\\Catalina\\localhost\\[网站名]\\org\\apache\\jsp
在这个文件夹中可以看到编译后的one.java和one.class两个文件
打开one.jsp,找到_jspService方法查看代码:
可以看到倒数第四行定义了JspWriter的实例化对象out;倒数第六行定义了ServletContext的实例化对象application和HttpSession实例化对象session。这好像就和Servlet联系起来了。
再返回one_jsp.java的继承类,可以看到
继承了HttpJspBase类,通过官方文档可以看到
确实继承了HttpServlet。说明Http服务器编译one.jsp生成的one_jsp.java文件确实是一个Servlet接口实现类。
JSP运行原理
最上面说了new出一个Servlet接口实现类实例化对象后,会调用_jspService方法完成相应的功能。我们来看看这个方法干了什么。
首先,调用JSP时Servlet请求转发发送的Request和response就是传给_jspService的:
然后往后面看:
在这个大大的try catch中,可以看到输出的Hello World!是通过out对象写入响应体中的;原来one.jsp中定义的两个int类型的变量num1和num2也在此方法中被定义,并且以
int num1=100;
int num2=200;
out.write('\r');
out.write('\n');
out.print("num1的值为"+num1);
out.write('\r');
out.write('\n');
out.print("num2的值为"+num2);
被写入响应体。
所以调用jsp文件,就相当于请求http服务器自动帮忙写一写Servlet,将数据写入响应体。
啊!多么智能!什么时候能智能到自动写code呢?