在说JSP的原理之前,先简单介绍下JSP是怎么回事?JSP全名Java Server Pages,中文名叫Java服务器页面。为什么会有JSP技术,这还要从Servlet说起,当我们新建一个Servlet的时候,可以看到Servlet的doGet和doPost方法体中有响应的html片段代码。也就是每一次浏览器请求HTML页面的时候,需要在doGet和doPost中使用out.println()的方式将HTML页面的内容输出并返回给浏览器。
在Web开发最开始的时候,通常情况是美工将写好的HTML静态页面发给Java程序员。Java程序员在Servlet中调用Service拿到数据后,逐句复制html静态页面上的html语句到Servlet中,并根据情况将后端的数据与html片段拼接在一起,然后就是重复的out.println("用户名:"+user.username+"")的方式疯狂输出。
按这种方式,要想拼接数据并完整输出一个html页面,没有上百千行的out.println()是不可能的。所以此时就引出了JSP。
我们可以直接在JSP文件里写HTML代码,可以把它当做html文件。而且JSP中的HTML/CSS/JS等的写法和HTML文件中的写法是一模一样的。但它毕竟不是HTML,而且本质上差了十万八千里。JSP的本质上是一个Java类(Servlet),是在服务器上运行的,只不过它输出的结果是Html。
Web容器接收到以.jsp为扩展名的URL访问请求时,它将把该请求交给JSP引擎处理。Tomcat中的JSP引擎就是一个Servlet程序,它负责解释和执行JSP页面。每个JSP页面在第一次访问时,JSP引擎将它翻译成一个Servlet源程序,接着再把这个Servlet源程序编译成Servlet的Class类文件,然后再由Web容器调用普通Servlet程序一样的方式来装载和解释执行这个由JSP页面翻译成的Servlet程序。
浏览器请求服务器想要访问某一个jsp文件,先在tomcat服务器安装目录下的“\work\Catalina\localhost”的文件下,先判断是否已经存在翻译成java和.class的字节码文件,没有就将JSP转换成这两个文件,java文件的底层其实就是Servlet对象的创建并使用,都是通过获取response的输出流,再依次将jsp中的html代码依次写出。
脚本代码块。使用方式<% Java代码块 %>,两个脚本代码之间也可以嵌套Html标签,比如带有For循环的脚本代码。其实脚本代码都是在_jspService方法中原封不动输出的Java代码。
JSP的声明。使用方式为:<%! Java代码 %>,JSP声明中可以包括方法、变量等,这些都是放在_jspService()方法的同级下创建方法和变量。
JSP注释。使用方式为<%-- 注释内容 --%>,JSP注释不会再JSP页面上显示,Servlet中也不会存在,比较节约内存。
JSP Page指令:<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
静态与冬天的包含。包含其实就是讲其他的JSP引入到当前JSP文件中,将多个JSP的相同部分提炼出来,避免重复代码的编写。包含分静态和动态,静态包含只会生成一个Servlet,而动态包含会生成多个Servlet。
脚本表达式:<%=x>,就是具体的输出某个参数,或者某个方法的返回的结果。
错误页面:错误页面是指在JSP中Java代码执行出错时,跳转到出错界面中去,使用的方法是:
JSP的内置对象包括:Request、Response、Session、Page、ServletContext、ServletConfig、PageContext、Exception和JSPWriter。
这九大内置对象中的Request、Session、ServletContext、PageContext都是为域对象。四个域对象也存在一个等级范围,由小到大为:PageContext ---Request---Session----ServletContext。
pageContext是一个域对象,也可以获取其他八大内置对象的应用(Exception需要设置为错误页面)。可以自己模拟实现一个PageContext对象。
首先PageContext是一个域对象,所以在PageContext中存在一个Map集合,而且由于PageContext是可以获取到其他内置对象,所以在PageContext中都有其他内置对象的属性。
提供一个PageContext的设计工厂返回PageContext对象。
继承HttpServlet。