JSP详解
什么是JSP?
JSP(Java Server Pages) : 是以Java语言为基础的动态网页开发技术,其中既可以写html代码,也可以写java代码
特点 : 可以在html源码中嵌入java代码
为什么说JSP就是Servlet?
JSP页面会被编译成Servlet后才被执行.可以在tomcat根目录下work文件夹内找到项目的JSP编译成的Servlet文件
打开后就可以看到
public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent, org.apache.jasper.runtime.JspSourceImports {
其中HttpJspBase类继承自HttpServlet
我们编写的所有html代码,都会被转换成servlet中的out.write(html)代码输出.
JSP什么时候被编译成Servlet?
JSP只有在第一次客户端发送请求的时候才会被编译,之后的请求都是直接调用编译后的文件
如果JSP文件发生改动,tomcat会动态地检测到,然后在下一次收到请求的时候重新编译,所以改动jsp代码无需重新启动服务器.
因为JSP就是servlet,那么生命周期也就是跟serlvet一样
JSP和servlet有一点区别就在于:jsp是先部署后编译,而servlet是先编译后部署
一.JSP语法
JSP页面包括模板数据和元素
模板数据 : 就是JSP中的HTML代码,编译后的内容实例如下:所有模板数据都会用out.write()方法原样输出
out.write("\t\t\t<input class=\"submit\" type=\"submit\" value=\"登陆\"/>\r\n"); out.write("\t\t</form>\r\n"); out.write("\t</div>\r\n"); out.write("\t\r\n"); out.write("</div>\r\n"); out.write("<footer>你好啊!</footer>\r\n"); out.write("</body>\r\n"); out.write("</html>\r\n");
元素 : 包括脚本(JS和Java代码),JSP指令(Directive)和JSP标签(Tag).元素决定着程序的流程,元素是不会显示到浏览器的
所有jsp的模板数据和元素,都被编译在Servlet文件的_jspService()方法内,具体内容可以自己查看编译后的文件.
jsp元素在编译后变成普通的java代码
JSP脚本
1. 格式 : <% java代码 %>
所有jsp的模板数据和元素,都被编译在Servlet文件的_jspService()方法内,
所以,
JSP脚本中的代码就是在方法内部写代码.符合Java方法内的代码格式即可!
<% java代码 %>写在什么位置,编译后仍然在那个位置.(比如原来写在<h1>标签内部,那么编译后仍在那个位置)
out.write("<footer>你好啊!</footer>\r\n"); // 编译后示例 int a = 11; out.println(a); out.write("</body>\r\n");
2.格式 : <%=xxx %>
用来输出结果,不做赘述
3.格式 : <%! 方法或属性%>
在JSP中声明方法或属性(全局变量).
4.格式 : <%-- 注释内容 --%>
JSP注释
JSP指令
指令用来申明JSP页面的一些属性,比如编码方式,文档类型等等
格式 : <%@指令名 key="value"%>
常用指令有三种 : page指令, include指令, taglib指令
page指令 :
-------------------------------------------------------------------------------
属性名称 取值范围 描述
language java 解释该JSP文件时采用的语言,一般为java语言,默认为java
extends 任何类的全名 编译该JSP文件时继承哪个类,JSP为Servlet,因此当指明继承普通类时需要实现Servlet的init、destroy等方法
import 任何包名、类名 引入该JSP中用到的类、包等,import是唯一可以声明多次的page指令属性,一个import可以引用uogelei,中间用英文逗号隔开,
如<%@ page import="java.util.List,java.util.ArrayList"%>
session true、false 该JSP内是否内置Session对象,如果为true,则内置Session对象,可直接使用,否则反之,默认为true
autoFlush true,false 是否运行缓存,如果为true,则使用out.println()等方法输出的字符串并不是立刻到达客户端服务器的,而是暂时存到缓存里,缓存满
了或者程序执行完毕或者执行out.flush()操作时才到客户端,默认为true。
buffer none或者数字KB 指定缓存大小,当autoFlush设为true时有效,例如<%@ page buffer=10kb%>
isThreadSafe true,false 是否线程安全,如果为true,则运行多个线程同时运行该jsp程序,否则只运行一个线程,其余线程等待,默认为false
isErrorPage true,false 指定该页面是否为错误显示页面,如果为true,则该JSP内置有一个Exception对象exception,可直接使用,否则没有,默认为false
errorPage 某个JSP页面的相对路径 指明一个错误页面,如果该JSP程序抛出一个未捕捉的异常,则转到errorPage指定的页面,errorPage指定的页面通常
isErrorPage属性为true,且内置的exception对象为未捕捉的异常
contentType 有效的文档类型 客户端浏览器根据该属性判断文档类型,例如 HTML格式为text/html、纯文本格式为text/plain、JPG图像为image/jpeg、
GIF图像为image/gif、WORD文档为application/msword,该属性常跟着charset设置编码一起,作用是通知服务器和浏览器都使用同一个码表
info 任意字符串 指明JSP的信息,该信息可以通过Servlet.getServletInfo()方法获取到
trimDirective Whitespaces true、false 是否去掉指令前后的空白字符,默认为false
pageEncoding UTF-8,ISO-8859-1等 指定一张码表来对该JSP页面进行编码,
------------------------------------------------------------------------------
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
其中,pageEncoding="UTF-8是指以UTF-8编码编译为Servlet
contentType="text/html; charset=UTF-8"会在Servlet中变成 : response.setContentType("text/html; charset=UTF-8");
include指令
<%@ include file="relativeURL"%> 静态包含
taglib指令
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> 引入标签库
JSP行为
元素有包括脚本,指令,标签,标签分为内置标签和taglib标签库标签以及自定义标签,
其中内置标签就是JSP行为
JSP行为其实是对常用的JSP功能的抽象与封装,可以取代jsp脚本,让JSP中就少一些嵌入java代码的地方
格式 : <jsp:行为名 key="value">
include行为
<jsp:include page=" " flush="true"/> 动态引入
------------------------------------------------------------
JavaBean行为包括 useBean行为, setProperty行为, getProperty行为
useBean行为
<jsp:useBean id="beanObject" class="className" scope="Value"> 声明一个JavaBean对象(是对象)
id : 变量名
class : javabean路径
scope : 作用域(request, page, session, application)
setProperty行为
<jsp:setProperty name="beanName" property="propertyName" value="xxx">给指定bean属性赋值
<jsp:setProperty name="user" property="*" />
可以自动给JavaBean对象的属性赋值,值从request中取,*代表所有属性
getProperty行为
<jsp:getProperty name="beanName" property="propertyName" /> 获取指定属性的值
--------------------------------------------------------
<jsp:forward />行为
Servlet中的请求转发代码 : request.getRequestDispatcher("someServlet").forward(request,response);
forward行为可以实现同样的效果(forward行为其实是对请求转发代码的封装)
格式如下:
<jsp:forward page="someServlet">
<jsp:param name="param1" value="value1"/> //携带请求参数
<jsp:param name="param2" value="value2"/>
</jsp:forward>
---------------------------------------------------------
<jsp:directive/>行为
directive行为,就相当于JSP指令,比如<jsp:directive.page/>相当于<%@ page %>指令,等等其它指令是一样的书写格式
二.JSP隐藏的九大内置对象和四大作用域
JSP九大内置对象分别是:
page、config、application、request、response、session、out、exception、pageContext
page:page对象代表当前JSP页面,是当前JSP编译后的Servlet类的对象。相当于this。
config:标识Servlet配置,类型:ServletConfig,api跟Servlet中的ServletConfig对象是一样的,能获取该servlet的一些配置信息,能够获取ServletContext
application:标识web应用上下文,类型:ServletContext,详情就看Servlet中的ServletContext的使用
request:请求对象, 类型:httpServletRequest
response:响应对象 类型:httpServletResponse
session:表示一次会话,在服务器端记录用户状信息的技术
out:输出响应体 类型:JspWriter, JspWriter继承了java.io.Writer类
exception 表示发生异常对象,类型 Throwable,在上面我们介绍page指令中的一个errorPage属性时就有说到他
pageContext:表示 jsp页面上下文(jsp管理者) 类型:PageContext
标记了红色的对象就是JSP独有的,其他的都是Servlet中的老东西。
少了exception对象,因为我们在将page指令时,说过一个isErrorPage属性,默认是false,被关闭了,所以其中并没有exception对象
------------------------------------------------------------------------------------
out对象:
类型是JspWriter, JspWriter继承自java.io.Writer类
out输出方法 :
out.write() ==>是继承自Writer类里的方法
out.println()/out.print() ==>是JspWriter自己的方法
JSP缓存和Servlet缓存
out对象是JspWriter类型的,所以是会先将要发送的数据存入JSP输出缓存中,等JSP输出缓存满了在自动刷新到servlet输出缓存
等serlvet输出缓存满了,或者程序结束了,就会将其输出到浏览器上。除非手动out.flush()。
而jsp 输出底层使用 response.getWriter(),则是直接将数据存储到servlet输出缓存.
这时,输出顺序会是 bbbaaaccc,
如果把out.flush()的注释消掉,那么结果会是 : aaabbbccc.
pageContext对象
它是JSP页面的管理者(上下文),所以JSP中的内置对象呀,它统统能够获
1.获得其它八大内置对象 : getXxx()
2.操作page作用域的属性 : getAttribute(), setAttribute(), removeAttribute()
3.操作指定作用域的属性 : 在上边方法的形参中加入scope参数(4个作用域的scope值分别是1,2,3,4).
4.提供作用域常量 : PageContext.PAGE_SCOPE 值为1, 其他三个值分别为2,3,4
5.获取指定属性 : findAttribute(name) ===>从page,request,session,application中依次查询,直到获取为止
四大作用域
page、request、session、application
其中,request,session,application都有setAttribute()和getAttribute()方法,可以在域中存取数据,request的setParameter()方法是设置请求参数,不是存储到域中
page的存取数据依靠pageContext对象来执行.
page : 变量的作用域只在当前页面
request : 变量在一次请求中,可能包含多个页面,比如页面转发
session : 变量在一次会话中,是要cookie不关闭,session就会起作用
application : 代表变量能一个应用下的多个会话, 在服务器下的多个项目之间都能够使用.