# 1. JSP 的介绍与创建JSP 的全称是 Java Server Pages,即 Java 的服务器页面JSP 的主要作用是代替 Servlet 程序回传 HTML 页面的数据web 目录 (或其他) 右击 --> new --> JSP/JSPX --> 输入文件名 --> 选择 JSP file 创建# 2. JSP 的本质JSP 页面本质上是一个 Servlet 程序,第一次访问 JSP 页面时 (运行 Tomcat 服务器后在浏览器地址栏输入路径),Tomcat 服务器会将此 JSP 页面翻译成为一个 Java 源文件,并对其进行编译成为.class 字节码文件 (一个.java,一个.class),当打开.java 文件时发现其中的内容是:
而 HttpJspBase 类直接继承于 HttpServlet 类,即 JSP 翻译出来的 Java 类间接继承于 HttpServlet 类,证明 JSP 页面是一个 Servlet 程序
# 3. JSP 的语法JSP 头部的 page 指令:
JSP 头部的 page 指令可以修改 JSP 页面中的一些重要属性或行为
(以下属性均写在 page 指令中,默认 page 指令中没有出现的属性都采用默认值):
contentType 属性:表示 JSP 返回的数据类型是什么,即 response.setContentType () 的参数值language 属性:表示 JSP 翻译之后是什么语言文件 (目前只支持 Java)pageEncoding 属性:表示当前 JSP 文件本身的字符集 (可在 IDEA 右下角看到)import 属性:表示导包 (导类),与 Java 一致autoFlush 属性:设置当 out 输出流缓冲区满了之后是否自动刷新缓冲区,默认值是 truebuffer 属性:设置 out 缓冲区的大小,默认是 8kb
注意:out 缓冲区满了之后不能自动刷新的话会报错errorPage 属性:设置当 JSP 页面运行出错时自动跳转到的页面 (错误信息页面) 的路径,这个 路径一般都是以斜杠打头,表示请求的地址是 http://ip:port / 工程路径 /,对应代码 web 目录isErrorPage 属性:设置当前 JSP 页面是否是错误信息页面,默认是 false,如果是 true 可以 获取错误信息session 属性:设置访问当前 JSP 页面时是否会创建 HttpSession 对象,默认值是 trueextends 属性:设置 JSP 页面翻译出来的 Java 类默认继承谁注意:以上默认值除非有特殊需要,否则不建议修改
# 4. JSP 中的常用脚本# 4.1 声明脚本格式:<%! 声明 Java 代码 %>
作用:可以给 JSP 翻译出来的 Java 类定义属性、方法、静态代码块、内部类等
特点:不会在浏览器的页面上显示出来,仅存在于翻译后的 Java 类中
代码演示:声明脚本的使用 (此 JSP 文件在 web 目录下,名为 First.jsp)
代码语言:javascript代码运行次数:0运行复制<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.Map" %>
<%--1.声明类属性--%>
<%!
private String name;
private static Map
%>
<%--2.声明类方法--%>
<%!
public int sum() {
return 12;
}
%>
<%--3.声明静态代码块--%>
<%!
static {
map = new HashMap
map.put("key1", "value1");
}
%>
对应的翻译后的 java 源文件:
# 4.2 表达式脚格式:<%= 表达式 %>
作用:在浏览器的 JSP 页面上输出数据 (只有此脚本可以在浏览器的页面上输出数据)
特点:
(1) 所有的表达式脚本都会被翻译到对应的 Java 类的_jspService () 方法中,故表达式脚本可以 直接使用_jspService () 方法参数中的对象
(2) 表达式脚本都会被编译后的 Java 类中的 out.print () 方法输出到浏览器页面上
(3) 表达式脚本中的表达式不能以分号结束
代码演示:表达式脚本的使用 (此 JSP 文件在 web 目录下,名为 First.jsp)
代码语言:javascript代码运行次数:0运行复制<%=22 %>
<%="可以输出字符串" %>
<%=map %>
<%--使用_jspSe=rvice方法中的对象--%>
<%=request.getParameter("username") %>启动 Tomcat 服务器后浏览器的运行结果:
对应的翻译后的 Java 源文件 (在_jspService 方法中):
注意:
write 方法中的标签、转义字符自动识别为对应的
功能,不在页面输出,执行各自代表的功能out 的两个方法也在_jspService 方法中,也都是 java 语言只有 print、write 方法、表达式脚本中的内容才可在浏览器中显示,其余 Java 代码的 sout 在控制台输出# 4.3 代码脚本格式:<% Java 语句 %>
作用:在 JSP 页面中可以编写需要的 Java 代码
特点:
(1) 代码脚本翻译后都在_jspService 方法中,故代码脚本可以直接使用此方法参数中的对象
(2) 可以由多个代码脚本块组合完成一个完整的 Java 语句
(3) 代码脚本还可以和表达式脚本一起组合使用,在 JSP 页面上输出数据
代码演示:代码脚本的使用 (此 JSP 文件在 web 目录下,名为 First.jsp)
代码语言:javascript代码运行次数:0运行复制<%--1.if语句--%>
<%
int i = 1;
if (i == 1) {
System.out.println("我爱祖国!");
} else {
System.out.println("我很爱祖国!");
}
%>
<%--2.for循环语句--%>
<%
for (int j = 0 ; j < 3; j++) {
System.out.println("第" + j + "次循环");
}
%>
<%--3.使用_jspService方法参数中的对象--%>
<%
String username = request.getParameter("username");
System.out.println("username对应的值为:" + username);
%>运行结果:
启动 Tomcat 服务器后在地址栏输入:http://localhost:8080/MyTest/First.jsp?username=Jaychou
对应的翻译后的 Java 源文件 (在_jspService 方法中):
# 5. JSP 三种注释HTML 注释:
HTML 注释会被翻译到 JSP 文件对应的 Java 类的_jspService 方法中,以 out.write () 输出到客户端,
write 方法会自动识别标签,执行标签对应的功能,不会在浏览器的页面上输出注释Java 注释:(1) // 单行注释 (2) /*多行注释*/
Java 注释要写在声明脚本和代码脚本中才被认为是 Java 注释,会被翻译到 JSP 文件对应的 Java 类的_jspService 方法中,在对应的 Java 类中也是注释JSP 注释:<%- - 这是 JSP 注释 - -%>
JSP 注释中的内容不会在 JSP 文件翻译后的 Java 类中出现,即注释中的内容没有任何功能# 6. JSP 九大内置对象JSP 的内置对象指的是 Tomcat 服务器将 JSP 页面翻译为 Java 类之后内部提供的九大对象:
(将 page 指令的 isErrorPage 属性写成 true 可以出现 exception 对象)
request:请求对象
response:响应对象
pageContext:JSP 的上下文对象
session:会话对象
application:ServletContext 对象
config:ServletConfig 对象
out:JSP 输出流对象
page:指向当前 JSP 的对象
exception:异常对象
# 7. JSP 四大域对象
域对象是指可以像 Map 一样存取数据的对象,四个域对象功能一样,只是对数据的存取范围不同
代码演示 1:四个域对象存取数据的范围的不同 (在 web 目录下创建 scope1.jsp)
代码语言:javascript代码运行次数:0运行复制<%@ page contentType="text/html;charset=UTF-8" language="java" %>
scope1.jsp页面
<%
//向四个域对象中分别保存数据
pageContext.setAttribute("key", "pageContext");
request.setAttribute("key", "request");
session.setAttribute("key", "session");
application.setAttribute("key", "application");
%>
<%--
page属性设置请求转发的路径 --%>
代码演示 2:在 web 目录下创建 scope2.jsp
代码语言:javascript代码运行次数:0运行复制
scope2.jsp页面
<%-- JSP页面中不加任何标签直接输入的内容被write方法输出在浏览器的页面上 --%>
pageContext域是否有值:<%=pageContext.getAttribute("key")%>
request域是否有值:<%=request.getAttribute("key")%>
session域是否有值:<%=session.getAttribute("key")%>
application域是否有值:<%=application.getAttribute("key")%>
运行结果 1:
# 8. JSP 的 out 输出和 response.getWriter 输出的异同 相同点:response 表示响应,用于给客户端 (浏览器) 返回内容
out 同样也是用于给客户端 (浏览器) 输出内容
不同点:
注意:由于官方的代码中翻译后的 Java 代码底层都是使用 out 进行输出,故一般都使用 out 进行 输出,out 又分为 write 方法和 print 方法:
(1) out.print ():会将任何内容转换成字符串后调用 write 方法输出
(2) out.write ():输出字符串没有问题,但输出 int 型时会将 int 转换成 char 输出,导致输出的并非是想要的数字而是数字对应的 ASCII 码
结论:JSP 页面的代码脚本中任何要输出在浏览器的内容均使用 out.print () 方法
# 9. JSP 的常用标签# 9.1 静态包含(1) 使用场景:
(2) 使用方法:
<%@include file=“”%>
其中 file 属性设置要包含的 JSP 页面,以 / 打头,代表 http://ip:port / 工程路径 /,对应 web 目录
代码演示 1:在 web 目录下创建 body.jsp
代码语言:javascript代码运行次数:0运行复制
头部信息
主体信息
<%@include file="/foot.jsp"%>
代码演示 2:在 web 目录下创建 foot.jsp
代码语言:javascript代码运行次数:0运行复制
页脚信息
运行结果:
(3) 静态包含的特点:
①静态包含不会将被包含的 JSP 页面翻译成.java.class 文件
②静态包含是把被包含的页面的代码拷贝到 body.jsp 对应的 Java 文件的对应位置执行输出
# 9.2 动态包含(1) 使用方法:
其中 page 属性设置要包含的 JSP 页面,与静态包含一致
(2) 动态包含的特点:
①动态包含将被包含的 JSP 页面翻译成.java.class 文件
②动态包含还可以传递参数
③动态包含底层使用如下代码调用被包含的 JSP 页面执行输出:
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, “/foot.jsp”, out, false);
代码演示 1:在 web 目录下创建 body.jsp
代码语言:javascript代码运行次数:0运行复制
头部信息
主体信息
注意:
设置参数的标签要写在动态包含之中出现 Expecting “jsp:param” standard action with “name” and “value” attributes 异常,两个原因:
①动态包含中未设置参数但没有把
②动态包含中加了注释
代码演示 2:在 web 目录下创建 foot.jsp代码语言:javascript代码运行次数:0运行复制
页脚信息
<%=request.getParameter("username")%>
运行结果:
(3) 动态包含的底层原理:
# 9.3 ServletContextListener 监听器ServletContextListener 监听器可以监听 ServletContext 对象的创建和销毁 (web 工程启动时创建,停止时销毁),监听到创建和销毁之后都会调用 ServletContextListener 监听器的方法进行反馈:
代码语言:javascript代码运行次数:0运行复制public interface ServletContextListener extends EventListener {
//在ServletContext对象创建之后调用
public void contextInitialized(ServletContextEvent sce);
//在ServletContext对象销毁之后调用
public void contextDestroyed(ServletContextEvent sce);
}
123456# 9.4 ServletContextListener 监听器的使用步骤(1) 编写一个类实现 ServletContextListener 接口
(2) 重写两个方法
(3) 在 web.xml 文件中配置监听器
代码演示 1:创建一个类
代码语言:javascript代码运行次数:0运行复制public class ListenerTest implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext对象创建");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext对象销毁");
}
}代码演示 2:在 web.xml 中配置
代码语言:javascript代码运行次数:0运行复制
运行结果:
Tomcat 服务器启动之后控制台输出 ServletContext 对象创建
Tomcat 服务器停止之后控制台输出 ServletContext 对象销毁
注意:
查看翻译后的 Java 源文件的方法:启动 Tomcat 服务器访问到 JSP 页面之后在控制台输出的信息的前端找到 Using CATALINA_BASE 中的路径,在硬盘中打开此目录,点击 work --> Catalina --> localhost,找到对应的工程文件夹寻找即可访问 JSP 页面其实是在执行对应的翻译后的 Java 代码的_jspService 方法:翻译后的 Java 类中没有 service 方法,而是重写了父类的_jspService 方法,这个方法会被父类的 service 方法调用