1.jsp概述
JSP是javaee提供的动态web资源开发技术之一。
Servlet技术本质上是java代码,在其中编写HTML页面是比较困难的,为了简化这个过程,SUN公司提供了JSP技术,看起来非常类似于一个HTML页面,但是可以直接在其中编写java代码,从而将之前Servlet在java代码中嵌入html的过程,改为了JSP在HTML中嵌入java代码,便于开发动态页面。
2.jsp原理
2. JSP原理
a. jsp页面在第一次被访问的时候,会被jsp翻译引擎翻译为一个Servlet文件。其中页面的HTML和Java代码全部包含在文件内。访问jsp页面,就是访问这个Servlet文件,会使其中的Service()方法执行。
b. index_jsp.java文件内的类继承了HttpJspBase.HttpJspBase是一个Servlet,所以当前类也是一个Servlet
c. 实验:
i. 自行寻找work目录下的jsp页面
开发jsp页面并进行访问,观察[tomcat]/work/Catalina/[虚拟主机]\[web应用]\org\apache\jsp\xxx.java文件,了解jsp被翻译成对应的servlet的细节。
3.jsp语法
3.1 模板元素
jsp页面中的html内容,称之为模板元素。
模板元素在被翻译到Servlet时,直接被out.write输出到了浏览器。
3.2脚本表达式
语法:<%=JSP脚本表达式%> 直接量或具有返回值的表达式request.getContextPath()
脚本表达式会被jsp翻译引擎翻译为表达式的结果值。
翻译前:
翻译后:
页面中的jsp脚本表达式,在被翻译为servlet文件时,会放在servlet文件对应的位置上,在计算结果后,通过out.print()输出到页面。
3.3脚本片段
语法:<%JSP脚本片段%>
脚本片段会被jsp翻译引擎翻译为java代码。
翻译后的:
页面中的JSP脚本片段,在被翻译为servlet文件时,会被原封不动的翻译成java语句,出现在servlet文件的对应位置。并且脚本片段可以书写成多个部分。每一个部分都可以不完整。但是需要保证这些不完整的部分在翻译为servlet文件后,可以组成完整的java代码,即可编写。就是我们可以分开来写
3.4.jsp声明
基本语法:<%! 若干语句%>
JSP声明的内容,会被复制粘贴到翻译过来的Servlet的类的内部,成为类的成员。
主要用来为翻译过来的Servlet增加类的成员 - 包括成员属性 成员方法 静态成员 静态代码块 内部类 等等
jsp声明可以看做是整个类的变量和方法,如果需要调用,则可以在页面中的任意位置调用。
3.5.jsp注释
语法:<%-- JSP注释 --%>
<!--HTML注释--> | HTML注释会被翻译为模板元素,但是由于是HTML注释的内容,所以不会在页面中产生输出 |
<%//java注释%> | java注释会被翻译为java代码,出现在servlet文件对应的位置,由于是注释,所以不会产生任何的代码输出。 |
<%-- JSP注释 --%> | jsp注释在被翻译为servlet文件的过程中,就会被抛弃。不会出现在servlet文件中。注意:慎用! |
3.6jsp指令
基本语法:<%@jsp指令名称 属性名=属性值..%>
JSP指令不产生任何直接的输出,它是用来控制jsp翻译引擎如何将当前jsp页面翻译成Servlet的。
注意:jsp指令可以出现在页面中的任意一行。 jsp指令可以在页面中多次出现。
jsp指令一共有三种类型:
page指令:指定jsp页面的基本属性,决定了jsp翻译引擎在翻译jsp为servlet过程中的行为
include指令:在当前jsp页面中包含其它jsp页面即导入页面
taglib指令:引入标签库
a. page指令:
声明当前jsp页面的基本属性。控制jsp翻译引擎如何翻译jsp到servlet。
language="java" | 当前JSP使用的开发语言 |
extends="package.class" | 当前jsp翻译成servlet后要继承的类,注意此值必须是一个servlet的子类,一般情况下不要改 当我们的jsp页面被翻译成servlet文件的时候会自动继承HttpJspBase这个类,HttpjspBase是一个servlet,如果修改了这个指令的话,jsp就无法被翻译成servlet了 |
import="{package.class | package.*}, ..." | 导入需要使用到的包 java.lang.*;javax.servlet.*;javax.servlet.jsp.*;javax.servlet.http.*; |
session="true | false" | 用来指定当前页面是否使用session,如果设置为true,则翻译过来的servlet中将会有对session对象的引用,于是可以直接在jsp中使用session隐式对象。但是这将导致一旦访问jsp就会调用request.getSession()方法,可能导致不必要的空间浪费。如果确定jsp中不需要session可以设为false,默认为true,需要用到session对象的话,最好自己后台手动创建就好 |
[ buffer="none | 8kb | sizekb" ] | out隐式对象所使用的缓冲区的大小,如果设置成0kb的话就是响应有什么东西我就输出什么东西,而不用先存储起来等缓存到一定大小后一并输出。 |
[autoFlush="true | false"] | out隐式对象是否自动刷新缓冲区,默认为true,不需要更改 |
[ isThreadSafe="true | false" ] | 翻译过来的servlet是否实现SingleThreadModel,默认为true,代表线程安全不需要SingleThreadModel,通常能实现我们也不实现,因为SingleThreadModel这个接口针对我们的多线程,越管理越乱 |
[ errorPage="relative_url" ] | 如果页面出错,将要跳转到的页面,除了在jsp中使用此属性指定错误页面外也可以在web.xml中配置整个web应用的错误页面,如果两个都设置则jsp中的此属性起作用.在web.xml中可以配置<error-page>标签,用户作为整个web应用的友好错误提示页面。意思是在jsp页面中使用指令指明错误页面路径的时候针对的是当前jsp页面。在web-inf/web.xml中配置的是针对整个web应用 |
[ isErrorPage="true | false" ] | 如果设置此属性为true,翻译过来的servlet中将含有Exception隐式对象,其中封装的就是上一个页面中抛出的异常对象 |
[ contentType="mimeType [ ;charset=characterSet ]" | "text/html ; charset=ISO-8859-1" ] | 和jsp乱码相关的指令,用来指定jsp输出时,设置的Content-Type响应头用来指定浏览器打开的编码,如果设置了这个的话,在jsp转成servlet文件后会在servlet文件中会增加一句 response.setContentType("text/html;charset=ISO-8895-1");具体的码表是看你设置的。这句话的意思是通知浏览器接收数据的编码格式,以及服务器看给浏览器规定的编码格式后,采用一样的编码格式发送数据 |
[ pageEncoding="characterSet | ISO-8859-1" ] | 服务器翻译jsp时使用的编码集.如果向防止jsp乱码,应该保证文件的保存编码和jsp翻译成servlet用的编码以及输出到浏览器后浏览器打开的编码一致.此属性一旦设置好,翻译引擎会间接帮我们设置content-type属性. |
1.pageEncoding 配置的是jsp从磁盘中解析成servlet文件时候的编码方式,同时开发工具(myeclipe ,eclipse 等)会根据pageEncoding中的编码方式来存储对应的jsp页面到磁盘
2.pageEncoding 可以在ContentType没有指定的时候,自动给ContentType赋值,保证页面的存取和读取和浏览器的交互时采用的编码一致,保证乱码的不出现
1.jsp页面中设置出错界面
error.jsp 这个是在页面出错的时候,做显示的
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <!DOCTYPE HTML> <html> <head> </head> <body> 服务器爆炸了,维修中~~~~~~~ </body> </html>
出错页面Index.jsp页面
<%@ page language="java" import="java.util.*" pageEncoding="utf-8" errorPage="error.jsp" //相对路径设置出错后显示的出错界面 %> <!DOCTYPE HTML> <html> <head> </head> <body> <%=1/0 %> //发生算数异常错误 <%@include file="/head.jsp" %> this is index <%@include file="/foot.jsp" %> </body> </html>
运行结果
2.web-inf/web.xml 设置全局页面的错误页面显示
web.xml中的代码
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <display-name></display-name> <!-- 当前web应用的友好错误提示 --> <error-page> <error-code>404</error-code> <location>/error/404.jsp</location> </error-page> <error-page> <error-code>500</error-code> <location>/error/500.jsp</location> </error-page> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
error-code是状态码的意思,针对不同的状态码可以显示不同的错误页面
<exception-type>是异常类型,但是如果针对异常类型分的话太多了,空指针异常啥的,所以优先使用error-code
因为web.xml是针对整个web应用的错误提示,所以如果两种方法都有设置,优先使用的是第一种错误设置
1.[ isErrorPage="true | false" ]的使用
[ isErrorPage="true | false" ] 是用来设置当前页面是否使用exception隐式对象,
产生错误的页面
<%@ page language="java" import="java.util.*" pageEncoding="utf-8" session="false" errorPage="jsp02.jsp" //2.产生错误后跳转的错误显示页面 %> <%@page import="java.io.FileOutputStream,java.io.FileInputStream" %> <!DOCTYPE HTML> <html> <head> </head> <body> <%int i = 1/0; %> //1.产生错误 </body> </html>
跳转到的页面
<%@ page language="java" import="java.util.*" pageEncoding="utf-8" session="false" isErrorPage="true" %> <!DOCTYPE HTML> <html> <head> </head> <body> <%=exception.getMessage() %> //打印错误的信息 </body> </html>
结果显示
b. include指令
<%@include file="url"%>
在当前jsp页面中引入其他jsp页面,组合成一个jsp进行输出,如果网页某部分重复的出现很多次,可以独立成一个单独的jsp而在其他jsp中进行引入即可。
<body> <%@include file="/head.jsp" %> this is index <%@include file="/foot.jsp" %> </body>
c. taglib指令
<%@ taglib uri="" prefix=""%>
在当前页面中引入标签库。
3. 九大隐式对象
在jsp页面被翻译为servlet文件之后,有九个对象可以直接使用,又没有显式的定义,所以这九个对象就称之为九大隐式对象
page | 代表servlet文件的隐式对象 是jsp页面被jsp引擎翻译后的servlet文件 |
request | 代表HTTP请求隐式对象 即HttpServletRequest对象 |
response | 代表HTTP响应隐式对象 即HttpServletResponse对象 |
application | 代表当前web应用的隐式对象 即ServletContext对象 ,servlet的全局配置 |
config | 代表当前servlet配置信息的隐式对象 即servletConfig对象 |
session | 代表当前会话的HttpSession对象 |
out | 代表向页面输出的缓冲区的jspWriter隐式对象out.write ()out.print() |
exception | 代表上一个页面错误信息的隐式对象,当前页面接收到的Throwable类型异常信息对象 |
pageContext | 代表当前jsp页面上下文的隐式对象 即PageContext类型对象,是被jsp引擎翻译之前的 |
4.PageContext详解
PageContext代表当前jsp页面的执行环境的对象
a.PageContext功能1:作为入口获取其他八大隐式对象
pageContext.getPage();---获取page隐式对象
pageContext.getRequest();---获取request隐式对象
pageContext.getResponse();---获取response隐式对象
pageContext.getSession();---获取session隐式对象
pageContext.getServletConfig();---获取config隐式对象
pageContext.getServletContext();---获取application隐式对象
pageContext.getException();---获取exception隐式对象
pageContext.getOut();---获取out隐式对象
b. pageContext功能二--作为域对象使用
域对象:如果一个对象身上有一个可以被看见的范围,在这个范围内利用对象身上的map实现数据的共享,这个对象就可以称之为域对象。
操作api:
setAttribute(String name,Object obj);
getAttribute(String name);
removeAttribute(String name)
getAtrributeNames();
生命周期:
在访问jsp页面时,产生pageContext对象,生命周期开始。
在结束访问jsp页面是,pageContext对象销毁,生命周期结束。
作用范围:
整个jsp页面。
主要功能:
在整个jsp页面内共享数据。
<h3>功能二--pageContext作为域对象使用</h3> <% pageContext.setAttribute("name", "丽丽"); %> <%=pageContext.getAttribute("name") %>
c. 可以作为入口操作四大作用域
pageContext本身是一个域,但同时也是一个通用入口,可以通过该对象操作四大作用域中的属性。
相关方法
setAttribute(Object name,Object value,int scope)
getAttribute(Object name,int scope)
removeAttribute(Object name,int scope)
getAttributeNames()
其中scope可以取值如下,代表从指定域中操作域属性:
PageContext.APPLICATION_SCOPE | application域 |
PageContext.SESSION_SCOPE | session域 |
PageContext.REQUEST_SCOPE | request域 |
PageContext.PAGE_SCOPE | page域 |
例子:
<h3>功能三--获取设置其他域中的值</h3> <% pageContext.setAttribute("country", "China", PageContext.APPLICATION_SCOPE); pageContext.setAttribute("country", "US", PageContext.SESSION_SCOPE); pageContext.setAttribute("country", "UK", PageContext.REQUEST_SCOPE); pageContext.setAttribute("country", "Canada", PageContext.PAGE_SCOPE); %> <%=pageContext.getAttribute("country", PageContext.APPLICATION_SCOPE) %> <%=pageContext.getAttribute("country", PageContext.SESSION_SCOPE) %> <%=pageContext.getAttribute("country", PageContext.REQUEST_SCOPE) %> <%=pageContext.getAttribute("country", PageContext.PAGE_SCOPE) %>
d. 功能四---自动搜寻域
另外PageContext提供了如下方法,可以无需指定作用域,可以自动按照由小到大搜寻查找四大作用域中指定名称的属性并返回该属性值,只要找到立即返回,如果都找不到,返回null。
findAttribute(String name)
e.便捷的请求转发
<%pageContext.forward("/index.jsp"); %>
四大作用域
。 1. 什么是作用域
在javaweb开发中,提供了四大作用域,在不同范围和不同生命周期内,共享数据。本质上就是在一个可以在一定时间和一定范围内被共享的对象身上的map中共享数据的过程。
2. 四大作用域
由大到小排列:
ServletContext域 - ApplicationScope
作用范围:
整个web应用
生命周期
web应用加载,立即创建代表当前web应用的ServletContext对象,生命周期开始,服务器关闭或web应用被移出出容器时,随着web应用的销毁,ServletContext对象被销毁,生命周期结束。
主要功能
在整个web应用范围内共享数据
session域 - SessionScope
作用范围:
当前会话范围
生命周期:
当第一调用request.getSession()时创建session。
当 超时、手动调用invalidate方法、服务器异外关闭时销毁
主要功能:
在会话范围内共享数据
request域 - RequestScope
作用范围:
本次请求范围
生命周期:
请求开始,服务器创建代表请求的request对象,生命周期开始,请求结束,request销毁,生命周期结束
主要功能:
在请求转发过程中,由上游向下游传递域属性
pageContext域 - pageScope
作用范围:
当前jsp页面
生命周期:
当前jsp页面访问开始时创建,当前jsp页面访问结束时销毁
主要功能:
在当前jsp页面范围内共享数据。
且是四大作用域的通用操作对象,可以通过此对象操作四大作用域。