JSP 页面本质上是一个 Servlet 程序,第一次访问 JSP 页面时 (运行 Tomcat 服务器后在浏览器地址栏输入路径),Tomcat 服务器会将此 JSP 页面翻译成为一个 Java 源文件,并对其进行编译成为.class 字节码文件 (一个.java,一个.class),当打开.java 文件时发现其中的内容是:
而 HttpJspBase 类直接继承于 HttpServlet 类,即 JSP 翻译出来的 Java 类间接继承于 HttpServlet 类,证明 JSP 页面是一个 Servlet 程序
JSP 头部的 page 指令:
JSP 头部的 page 指令可以修改 JSP 页面中的一些重要属性或行为 (以下属性均写在 page 指令中,默认 page 指令中没有出现的属性都采用默认值):
注意:以上默认值除非有特殊需要,否则不建议修改
格式:<%! 声明 Java 代码 %> 作用:可以给 JSP 翻译出来的 Java 类定义属性、方法、静态代码块、内部类等 特点:不会在浏览器的页面上显示出来,仅存在于翻译后的 Java 类中
代码演示:声明脚本的使用 (此 JSP 文件在 web 目录下,名为 First.jsp)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.Map" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--1.声明类属性--%>
<%!
private String name;
private static Map<String, Object> map;
%>
<%--2.声明类方法--%>
<%!
public int sum() {
return 12;
}
%>
<%--3.声明静态代码块--%>
<%!
static {
map = new HashMap<String, Object>();
map.put("key1", "value1");
}
%>
</body>
</html>
对应的翻译后的 java 源文件:
格式:<%= 表达式 %> 作用:在浏览器的 JSP 页面上输出数据 (只有此脚本可以在浏览器的页面上输出数据) 特点: (1) 所有的表达式脚本都会被翻译到对应的 Java 类的_jspService () 方法中,故表达式脚本可以 直接使用_jspService () 方法参数中的对象 (2) 表达式脚本都会被编译后的 Java 类中的 out.print () 方法输出到浏览器页面上 (3) 表达式脚本中的表达式不能以分号结束
代码演示:表达式脚本的使用 (此 JSP 文件在 web 目录下,名为 First.jsp)
<%=22 %> <br/>
<%="可以输出字符串" %> <br/>
<%=map %> <br/>
<%--使用_jspSe=rvice方法中的对象--%>
<%=request.getParameter("username") %>
启动 Tomcat 服务器后浏览器的运行结果:
对应的翻译后的 Java 源文件 (在_jspService 方法中):
注意:
格式:<% Java 语句 %> 作用:在 JSP 页面中可以编写需要的 Java 代码 特点: (1) 代码脚本翻译后都在_jspService 方法中,故代码脚本可以直接使用此方法参数中的对象 (2) 可以由多个代码脚本块组合完成一个完整的 Java 语句 (3) 代码脚本还可以和表达式脚本一起组合使用,在 JSP 页面上输出数据
代码演示:代码脚本的使用 (此 JSP 文件在 web 目录下,名为 First.jsp)
<%--1.if语句--%>
<%
int i = 1;
if (i == 1) {
System.out.println("我爱祖国!");
} else {
System.out.println("我很爱祖国!");
}
%> <br/>
<%--2.for循环语句--%>
<%
for (int j = 0 ; j < 3; j++) {
System.out.println("第" + j + "次循环");
}
%> <br/>
<%--3.使用_jspService方法参数中的对象--%>
<%
String username = request.getParameter("username");
System.out.println("username对应的值为:" + username);
%>
运行结果: 启动 Tomcat 服务器后在地址栏输入:http://localhost:8080/MyTest/First.jsp?username=Jaychou
对应的翻译后的 Java 源文件 (在_jspService 方法中):
<!--HTML注释-->
HTML 注释会被翻译到 JSP 文件对应的 Java 类的_jspService 方法中,以 out.write () 输出到客户端,
write 方法会自动识别标签,执行标签对应的功能,不会在浏览器的页面上输出注释/*多行注释*/
Java 注释要写在声明脚本和代码脚本中才被认为是 Java 注释,会被翻译到 JSP 文件对应的 Java 类的_jspService 方法中,在对应的 Java 类中也是注释JSP 的内置对象指的是 Tomcat 服务器将 JSP 页面翻译为 Java 类之后内部提供的九大对象: (将 page 指令的 isErrorPage 属性写成 true 可以出现 exception 对象)
request:请求对象 response:响应对象 pageContext:JSP 的上下文对象 session:会话对象 application:ServletContext 对象 config:ServletConfig 对象 out:JSP 输出流对象 page:指向当前 JSP 的对象 exception:异常对象
域对象是指可以像 Map 一样存取数据的对象,四个域对象功能一样,只是对数据的存取范围不同
代码演示 1:四个域对象存取数据的范围的不同 (在 web 目录下创建 scope1.jsp)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>scope1</title>
</head>
<body>
<h1>scope1.jsp页面</h1>
<%
//向四个域对象中分别保存数据
pageContext.setAttribute("key", "pageContext");
request.setAttribute("key", "request");
session.setAttribute("key", "session");
application.setAttribute("key", "application");
%>
<%-- <jsp:forward page=""></jsp:forward>是请求转发标签,
page属性设置请求转发的路径 --%>
<jsp:forward page="/scope2.jsp"></jsp:forward>
</body>
代码演示 2:在 web 目录下创建 scope2.jsp
<head>
<title>Title</title>
</head>
<body>
<h1>scope2.jsp页面</h1>
<%-- JSP页面中不加任何标签直接输入的内容被write方法输出在浏览器的页面上 --%>
pageContext域是否有值:<%=pageContext.getAttribute("key")%> <br>
request域是否有值:<%=request.getAttribute("key")%> <br>
session域是否有值:<%=session.getAttribute("key")%> <br>
application域是否有值:<%=application.getAttribute("key")%> <br>
</body>
运行结果 1:
(1) 使用场景:
(2) 使用方法: <%@include file=“”%> 其中 file 属性设置要包含的 JSP 页面,以 / 打头,代表 http://ip:port / 工程路径 /,对应 web 目录
代码演示 1:在 web 目录下创建 body.jsp
<body>
头部信息 <br>
主体信息 <br>
<%@include file="/foot.jsp"%>
</body>
代码演示 2:在 web 目录下创建 foot.jsp
<body>
页脚信息 <br>
</body>
运行结果:
(3) 静态包含的特点: ①静态包含不会将被包含的 JSP 页面翻译成.java.class 文件 ②静态包含是把被包含的页面的代码拷贝到 body.jsp 对应的 Java 文件的对应位置执行输出
(1) 使用方法: <jsp:include page=””></jsp:include> 其中 page 属性设置要包含的 JSP 页面,与静态包含一致
(2) 动态包含的特点: ①动态包含将被包含的 JSP 页面翻译成.java.class 文件 ②动态包含还可以传递参数 ③动态包含底层使用如下代码调用被包含的 JSP 页面执行输出: org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, “/foot.jsp”, out, false);
代码演示 1:在 web 目录下创建 body.jsp
<body>
头部信息 <br>
主体信息 <br>
<jsp:include page="/foot.jsp">
<jsp:param name="username" value="Jaychou"/>
<jsp:param name="password" value="root"/>
</jsp:include>
</body>
注意:
<body>
页脚信息 <br>
<%=request.getParameter("username")%>
</body>
运行结果:
(3) 动态包含的底层原理:
ServletContextListener 监听器可以监听 ServletContext 对象的创建和销毁 (web 工程启动时创建,停止时销毁),监听到创建和销毁之后都会调用 ServletContextListener 监听器的方法进行反馈:
public interface ServletContextListener extends EventListener {
//在ServletContext对象创建之后调用
public void contextInitialized(ServletContextEvent sce);
//在ServletContext对象销毁之后调用
public void contextDestroyed(ServletContextEvent sce);
}
123456
(1) 编写一个类实现 ServletContextListener 接口 (2) 重写两个方法 (3) 在 web.xml 文件中配置监听器
代码演示 1:创建一个类
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 中配置
<listener>
<!-- <listener-class>标签中写上述程序的全类名 -->
<listener-class>com.qizegao.servlet.ListenerTest</listener-class>
</listener>
运行结果: Tomcat 服务器启动之后控制台输出 ServletContext 对象创建 Tomcat 服务器停止之后控制台输出 ServletContext 对象销毁
注意: