JavaServer Pages
基于java语言实现的服务器端页面
JSP是JavaEE规范之一
JSP文件后缀默认是.jsp,但是jsp文件的后缀也可以修改的,通过修改CATALINA_HOME/conf/web.xml文件
JS : JavaScript,运行在浏览器中,和服务器没有关系,和java也没有关系
JSP : JavaServer Pages,运行在服务器中,JSP底层就是java程序,运行在JVM中。
JSP的执行原理:
- 浏览器上访问的路径虽然是以.jsp结尾,访问的是某个jsp文件,其实底层执行的是jsp对应的java程序
- Tomcat服务器负责将.jsp文件翻译生成.java源文件,并且将java源文件编译生成.class字节码文件
- 访问jsp,其实底层还是执行了.class文件中的程序。
- Tomcat服务器内置了一个JSP翻译引擎,专门负责翻译JSP文件,编译java源文件
- index.jsp会被翻译生成index_jsp.java,编译生成index_jsp.class
- index_jsp这个类继承了HttpJspBase,而HttpJspBase继承了HttpServlet
- jsp就是Servlet,只不过职责不同,JSP的强项做页面展示。
在JSP文件中编写的所有的HTML、CSS、JavaScript,对于JSP来说,只是普通的字符串。被翻译到:out.write("翻译到这里");
JSP文件修改之后,不需要重新部署,也不需要重新启动Tomcat服务器。
JSP文件第一次访问的时候为什么非常慢?
- 启动JSP翻译引擎
- 需要一个翻译的过程
- 需要一个编译的过程
- 需要Servlet对象的创建过程
- init方法调用
- service方法调用.....
为什么第2+次访问JSP的时候非常快?
- 不需要重新翻译
- 不需要重新编译
- 不需要创建Servlet对象
- 直接调用Servlet对象的service方法
JSP也是单实例多线程环境下运行的一个Servlet对象。
JSP文件在被修改之后会被重新翻译,Tomcat服务器会记录JSP文件的最后修改时间。
关于JSP的小脚本scriptlet:
<%----%> JSP的专业注释,使用这种注释方式,不会被翻译到java源文件中
<%
java语句;
java语句;
java语句;
%>
小脚本中的java语句被翻译到Servlet的service方法中,所以小脚本中必须编写“java语句”,java语句以分号结尾。
JSP的声明语法格式:
<%!
实例变量;
静态变量;
方法;
静态语句块;
构造函数;
.....
%>
注:
声明块中的java程序会被JSP翻译引擎翻译到service方法之外
声明块中不能直接编写java语句,除非是变量的声明
<% out.print(); %> 等同于 <%= %>
<%=i %> 表达式语法,具有输出功能,输出到浏览器上
关于JSP的九大内置对象:
1、内置对象可以直接在JSP文件中拿来使用。
2、九大内置对象
内置对象 完整类名
----------------------------------------------------------------------------
pageContext javax.servlet.jsp.PageContext 页面范围【页面上下文】
request javax.servlet.http.HttpServletRequest 请求范围
session javax.servlet.http.HttpSession 会话范围
application javax.servlet.ServletContext 应用范围
response javax.servlet.http.HttpServletResponse 响应对象
out javax.servlet.jsp.JspWriter 标准输出流
config javax.servlet.ServletConfig Servlet配置信息对象
exception java.lang.Throwable 异常引用(isErrorPage="true")
page javax.servlet.http.HttpServlet (page = this) 很少用
3、以上内置对象只能在service方法中“直接”使用,在其它方法中无法“直接”使用,可以间接使用。
从小到大依次为:
pageContext < request < session < application
pageContext : 在同一个JSP页面中共享数据,不能跨JSP页面
request : 在同一个请求中共享数据 【使用较多】
session : 在同一个会话中共享数据 【使用较多】
application : 所有用户共享的数据可以放到应用范围中
pageContext只能在同一个JSP页面中共享数据。范围是最小的。
通过pageContext这个页面上下文对象,可以获取当前页面中的其它对象。
<%=pageContext.getRequest() %>
<%=pageContext.getSession() %>
<%=pageContext.getServletContext() %>
<%=pageContext.getServletConfig() %>
pageContext对象传递数据:
pageContext.setAttribute(“username”,jack); //存
pageContext.getAttribute(“username”); //取
只能存储一个页面中的数据,无法跨页面。可以获取include指令包含的jsp页面中存储的数据,但是不能获取include动作包含的jsp页面中存储的数据。
使用pageContext对象往request,session,application对象中存储数据。
向request范围存储数据:
pageContext.setAttribute(“username”,”jack”,PageContext.REQUEST_SCOPE);
向session范围存储数据:
pageContext.setAttribute(“username”,”jack”,PageContext.SESSION_SCOPE);
向application范围存储数据:
pageContext.setAttribute(“username”,”jack”,PageContext.APPLICATION_SCOPE);
关于JSP的指令:
1、指令的作用,是指导JSP的翻译引擎如何翻译JSP代码。
2、JSP中共三个指令:
* page 页面指令
* include 包含指令
* taglib 标签库指令
3、指令的使用语法格式:
<%@指令名 属性名=属性值 属性名=属性值.....%>
4、关于JSP的page指令,page指令中常用的属性:
* contentType 设置JSP的响应内容类型,同时在响应的内容类型后面也可以指定响应的字符编码方式
* pageEncoding 设置JSP响应时的字符编码方式
* import 组织导入
* session 设置当前JSP页面中是否可以直接使用session内置对象
* errorPage 错误页面
* isErrorPage 是否是错误页面
* isELIgnored 是否忽略EL表达式
关于page指令中的session属性:
- session="true"
* 表示在当前JSP中可以直接使用内置对象session
* 程序执行的时候获取当前的session会话对象,若获取不到则新建session对象
- session="false"
* 表示在当前JSP中不能直接使用内置对象session
* 但是有一些业务可能要求在当前JSP页面中获取当前的session对象,没有获取到则不新建session对象,此时需要编写 以下程序
* <%@page contentType="text/html; charset=UTF-8" session="false"%>
* <%
* HttpSession session = request.getSession(false);
* %>
- 若session这个属性没有指定,默认值就是session="true"
关于page指令的errorPage属性:
当前JSP页面出错之后,要跳转的页面路径,需要使用该属性指定。
关于page指令中的isErrorPage属性:
- 用于错误页面
- isErrorPage = "false" 表示内置对象exception无法使用【缺省情况下是false】
- isErrorPage = "true" 表示内置对象exception可以使用
* <%-- 使用内置对象exception打印异常堆栈追踪信息 --%>
* <%-- exception引用指向了抛出的异常 --%>
* <%
* exception.printStackTrace();
* %>
例:<%@page contentType="text/html; charset=UTF-8" session="true" errorPage="/error.jsp"%>
<%@page contentType="text/html" %>
<%@page pageEncoding="UTF-8" %>
<%@page import="java.util.Date" %>(光标至于类名末尾,alt+/快捷导入)
关于include指令:
1、a.jsp可以将b.jsp包含进来,当然被包含的资源不一定是jsp,也可能是其它的网络资源
2、include作用:
在网页中有一些主体框架,例如:网页头、网页脚,这些都是固定不变的,
我们可以将网页头、网页脚等固定不变的单独编写到某个JSP文件中,
在需要页面使用include指令包含进来。
优点:
代码量少了
便于维护【修改一个文件就可以作用于所有的页面】
3、在一个jsp中可以使用多个include指令
4、include实现原理:
4.1 编译期包含
4.2 a.jsp包含b.jsp,底层共生成一个java源文件,一个class字节码文件,翻译期包含/编译期包含/静态联编
5、静态联编的时候,多个jsp中可以共享同一个局部变量。
因为最终翻译之后service方法只有一个。
例:<%@include file="/index2.jsp" %>
关于JSP中的动作:
语法格式:<jsp:动作名 属性名=属性值 属性名=属性值....></jsp:动作名>
关于JSP中的forward动作:
<jsp:forward page="/index2.jsp"></jsp:forward>
关于JSP中的include动作:
1、a.jsp包含b.jsp,底层会分别生成两个java源文件,两个class字节码文件
2、编译阶段并没有包含,编译阶段是两个独立的class字节码文件,生成两个Servlet,两个独立的service方法
3、使用include动作属于运行阶段包含, 实际上是在运行阶段a中的service方法调用了b中的service方法,达到了包含效果
4、a.jsp包含b.jsp,若两个jsp文件中有重名的变量,只能使用动态包含。其余都可以使用静态包含。
5、include动作完成的动态包含,被称为动态联编。
例:<jsp:include page="/b.jsp"></jsp:include>