JSP
- JSP概述
- JSP的本质
- JSP的三种语法
- JSP头部的page指令
- JSP中的常用脚本
- 声明脚本
- 表达式脚本
- 代码脚本
- JSP中的三种注释
- JSP的九大内置对象
- JSP四大域对象
- JSP中几种输出的区别
- JSP常用标签
- 静态包含
- 动态包含
- 转发标签
- Listener监听器
- ServletContextListener 监听器
- 创建监听器
JSP概述
JSP(Java Server Pages)是由Sun 公司专门为了解决动态生成HTML 文档的技术。
注:jsp 页面的访问千万不能像HTML 页面一样。托到浏览器中。只能通过浏览器访问Tomcat 服务器再访问jsp页面。
JSP的本质
jsp页面本质上是一个Servlet 程序。
当我们第一次访问jsp 页面的时候,Tomcat 服务器会帮我们把jsp 页面翻译成为一个java 源文件,并且对它进行编译成为.class 字节码程序。
查看生成的java源文件发现,自动生成的index_jsp类继承了org.apache.jasper.runtime.HttpJspBase类。
而HttpJspBase类继承了HttpServlet类,所以JSP本质是一个Servlet程序。
其底层实现,也是通过输出流。把html 页面数据回传给客户端。
JSP的三种语法
JSP头部的page指令
jsp 的page 指令可以修改jsp 页面中一些重要的属性,或者行为。
<%@ page contentType=“text/html;charset=UTF-8” language=“java” %>
page属性 | 属性作用 |
language 属性 | 表示jsp 翻译后是什么语言文件。暂时只支持java。 |
contentType 属性 | 表示jsp 返回的数据类型是什么。也是源码中response.setContentType()参数值 |
pageEncoding 属性 | 表示当前jsp 页面文件本身的字符集。 |
import 属性 | 跟java 源代码中一样。用于导包,导类。 |
autoFlush属性 | 设置当out 输出流缓冲区满了之后,是否自动刷新冲级区。默认值是true。 |
buffer 属性 | 设置out 缓冲区的大小。默认是8kb |
errorPage 属性 | 设置当jsp 页面运行时出错,自动跳转去的错误页面路径。 |
isErrorPage 属性 | 设置当前jsp 页面是否是错误信息页面。默认是false。如果是true 可以获取异常信息。 |
session 属性 | 设置访问当前jsp 页面,是否会创建HttpSession 对象。默认是true。 |
extends 属性 | 设置jsp 翻译出来的java 类默认继承谁。 |
buffer属性设置太小(一般不改该值默认8kb综合性能最好),或者autoFlush为false导致buffer缓冲区溢出会报异常:
java.io.IOException: Error: JSP Buffer overflow
errorPage表示错误后自动跳转去的路径(可以设置一个页面专门提示错误信息)
这个路径一般都是以斜杠打头,它表示请求地址为http://ip:port/工程路径/映射到代码的Web目录
isErrorPage 设置为true时,生成的jsp类中会多一个exception对象。
JSP中的常用脚本
声明脚本
声明脚本的格式是:
<%! 声明java 代码%>
作用:
可以给jsp 翻译出来的java 类定义属性和方法甚至是静态代码块、内部类等。
<%--声明脚本 不常用--%>
<%--1.声明类属性--%>
<%!
private Integer id;
private String name;
private static Map<String, Object> map;
%>
<%--2.声明static静态代码块--%>
<%!
static {
map = new HashMap<>();
map.put("key1", "value1");
map.put("key2", "value2");
map.put("key3", "value3");
}
%>
<%--3.声明类方法--%>
<%!
public int abc() {
return 12;
}
%>
<%--4.声明内部类 --%>
<%!
public static class A {
private Integer id = 12;
private String name;
}
%>
表达式脚本
表达式脚本的格式是:
<%=表达式%>
表达式脚本的作用:
在jsp 页面上输出数据。
表达式脚本的特点:
- 所有的表达式脚本都会被翻译到_jspService() 方法中
- 表达式脚本都会被翻译成为out.print()输出到页面上
- 由于表达式脚本翻译的内容都在_jspService() 方法中,所以_jspService()方法中的对象都可以直接使用。
- 表达式脚本中的表达式不能以分号结束。
<%--表达式脚本 常用--%>
<%--输出整型
输出浮点型
输出字符串
输出对象
--%>
<%=12%><br/>
<%=12.10%><br/>
<%="输出字符串"%><br/>
<%=map%><br/>
<%-- 可以使用_jspService()方法中的对象--%>
<%=request.getParameter("username")%><br/>
<%--不能加分号; --%>
<%--<%=request.getParameter("username")%;><br/>--%>
代码脚本
代码脚本的格式是:
<%
java 语句
%>
代码脚本的作用是:
可以在jsp 页面中,编写我们自己需要的功能(写的是java 语句)
代码脚本的特点是:
- 代码脚本翻译之后都在_jspService 方法中
- 代码脚本由于翻译到_jspService()方法中,所以在_jspService()方法中的现有对象都可以直接使用。
- 还可以由多个代码脚本块组合完成一个完整的java 语句。
- 代码脚本还可以和表达式脚本一起组合使用,在jsp 页面上输出数据
<%-- 代码脚本--%>
<%
System.out.println("java语句");
%>
<%-- if语句(可以多个代码脚本组合拼出一个完成的if语句)--%>
<%
int i = 12;
if (i == 12){
%>
<h1>i==12 --> 相等</h1>
<%
}else{
%>
<h1>i!=12 --> 不相等</h1>
<%
}
%>
<%-- for循环语句--%>
<table border="1" cellspacing="0">
<%
for (int j = 0; j < 10; j++) {
%>
<tr>
<td>第<%=j + 1%>行</td>
</tr>
<%
}
%>
</table>
<%-- _jspService()方法内的代码都可以写--%>
<%
String username = request.getParameter("username");
System.out.println("\n用户名的请求参数是:" + username);
%>
JSP中的三种注释
- HTML注释
<!-- 这是html 注释–>
html 注释会被翻译到java 源代码中。在_jspService 方法里,以out.writer 输出到客户端。
- java 注释
<%
// 单行java 注释
/* 多行java 注释*/
%>
java 注释会被翻译到java 源代码中。
- jsp 注释
<%-- 这是jsp 注释–%>
jsp 注释可以注掉jsp 页面中所有代码。
JSP的九大内置对象
jsp 中的内置对象,是指Tomcat 在翻译jsp 页面生成的Servlet 源代码中,内部提供的九大对象,叫内置对象。
jsp的九大内置对象
对象名 | 含义 |
pageContext | jsp的上下文对象 |
session | 会话对象 |
exception | 异常对象(需设置isErrorPage=true) |
appIication | ServletContext对象 |
config | ServletConfig对象 |
out | jsp输出流对象。 |
page | 指向当前jsp的对象 |
request | 请求对象 |
response | 响应对象 |
这些对象都在_jspService()方法内,所以在代码脚本和表达式脚本里都可以使用这些对象。
下图没有request、response对象,因为它们是Tomcat服务器创建的,不用手动生成
JSP四大域对象
域对象名 | 对象所属类 | 作用范围 |
pageContext | PageContextImpl | 当前jsp 页面范围内有效 |
request | HttpServletRequest | 一次请求内有效 |
session | HttpSession | 一个会话范围内有效(打开浏览器访问服务器,直到关闭浏览器) |
application | ServletContext | 整个web 工程范围内都有效(只要web 工程不停止,数据都在) |
域对象是可以像Map 一样存取数据的对象。四个域对象功能一样。不同的是它们对数据的存取范围。
四个域在使用的时候,优先顺序是他们范围从小到大的顺序。
pageContext
request
session
application
给每个域中存数据和获取数据的代码示例:
<body>
<h1>scope.jsp页面</h1>
<%
//往四个域中都分别保存了数据
pageContext.setAttribute("key","pageContext");
request.setAttribute("key","request");
session.setAttribute("key","session");
application.setAttribute("key","application");
%>
<%-- 获取每个域中的值--%>
pageContext域的值:<%=pageContext.getAttribute("key")%><br/>
request域的值:<%=request.getAttribute("key")%><br/>
session域的值:<%=session.getAttribute("key")%><br/>
application域的值:<%=application.getAttribute("key")%><br/>
</body>
JSP中几种输出的区别
- out输出和response.getWrite()输出的区别
response 经常用于设置返回给客户端的内容(输出)。
out 也是给用户做输出使用的。
当jsp页面中所有代码执行完成后会做以下两个操作:
- 执行out. flush()操作,会把out缓冲区中的数据
追加写入到response缓冲区末尾。 - 会执行response的刷新操作。把全部数据
写给客户端
由于jsp翻译成类之后,底层源代码都是使用out 来进行输出,所以一般情况下。我们在jsp 页面中统一使用out 来进行输出。避免打乱页面内容的顺序。
- out.write()和out.print()的区别
out.write() 输出字符串没有问题(输出数值会转换为char类型)
out.print() 输出任意数据都没有问题(底层都转换成为字符串后调用的write 输出)
JSP常用标签
静态包含
<%@ include file=""%> 就是静态包含
file属性指定你要包含的jsp页面的路径
路径中的第一个斜杠表示http://ip:port/工程路径/ 映射到代码的web目录
静态包含的特点:
- 静态包含不会翻译被包含的jsp页面(不会生成被包含的java文件)。
- 静态包含其实是把被包含的jsp页面的代码拷贝到包含的位置执行输出。(就是把被包含的jsp文件翻译到自己的生成的java文件中)
<%@ include file="/include/footer.jsp"%>
动态包含
<jsp:include page=""></jsp:include> 这是动态包含
page 属性是指定你要包含的jsp页面的路径
动态包含也可以像静态包含一样,把被包含的内容执行输出到包含位置
动态包含的特点;
- 动态包含会把包含的jsp页面也翻译成java代码(会生成被包含的java文件)
- 动态包含底层代码使用如下代码去调用被包含的jsp页面执行输出
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, “/include/footer.jsp”, out, false); - 动态包含,还可以传递参数
<jsp:include page="/include/footer.jsp">
<jsp:param name="username" value="jzy"/>
<jsp:param name="password" value="zjcs"/>
</jsp:include>
转发标签
<%
//代码脚本实现请求转发
request.getRequestDispatcher("/scope2.jsp").forward(request,response);
%>
<%--
<jsp:forward page="/scope2.jsp"></jsp:forward> 是请求转发标签,他的功能就是请求转发.
page属性设置请求转发路径
--%>
<jsp:forward page="/scope2.jsp"></jsp:forward>
Listener监听器
1、Listener 监听器它是JavaWeb 的三大组件之一。
JavaWeb 的三大组件分别是:Servlet 程序、Filter 过滤器、Listener 监听器。
2、Listener 它是JavaEE 的规范(接口)
3、监听器的作用是,监听某种事物的变化。然后通过回调函数,反馈给客户(程序)去做一些相应的处理。
ServletContextListener 监听器
ServletContextListener 它可以监听ServletContext 对象的创建和销毁。
ServletContext 对象在web 工程启动的时候创建,在web 工程停止的时候销毁。
监听到创建和销毁之后都会分别调用ServletContextListener 监听器的方法反馈。
创建监听器
创建步骤:
- 编写一个类去实现ServletContextListener
- 实现其两个回调方法
- 到web.xml 中去配置监听器
public class MyServletContextListenerImpl implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContext对象被创建了");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("ServletContext对象被销毁了");
}
}
XML文件配置信息:
<listener>
<listener-class>com.javaweb.listener.MyServletContextListenerImpl</listener-class>
</listener>