一、jsp的三大指令
1>jsp中有三大指令:page、include、taglib
2>jsp指令的格式:
<%@指令名称 属性=“值” 属性=“值”.......%>--------->特殊的标签
jsp的指令可以放在jsp页面的任何位置,但是一般都会把jsp指令放到jsp文件的最上方
3>jsp的任何指令在一个jsp文件中都是可以重复出现的:如
<%@ page language = "java"%>
<%@ page import = "java.util.*"%>
<%@ page pageEncoding = "UTF-8"%>
而用一个page指令也是可以搞定的:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
1.page指令
page指令没有必须属性,都是可选属性。即使没有出席那任何属性也是可以的,如:
<%@ page %>
1>page指令的pageEncoding和contentType属性:
1)pageEncoding属性:它用于指定当前jsp页面的编码格式,
只要当前指定的编码格式和右键点击当前jsp文件Properties属性看到的当前jsp文件的
编码文件的编码格式一致就不会出现乱码问题(但只要一个文件编辑的编码格式)和
打开的编码格式一致就不会出现乱码)
而服务器需要以pageEncoding的编码格式将jsp编译成.java的否则不能正确编译。
2)contentType属性:与response.setContentType()方法的作用相同
一是设置响应内容的编码格式
二是设置content-type响应头,告诉浏览器服务器响应协议的编码格式。
如,<%@ page contentType = "text/html;charset=utf-8"%>
在jsp页面对应的Servlet中就是以response.setContentType("text/html;charset=utf-8");
存在的。
注意:无论是page指令的pageEncoding属性contentType属性,默认值都是ISO8859-1
是不支持中文的,所以jsp页面存在中文的话一定要设置这两个属性。
1)以上两个属性如果只提供了一个,那么另一个属性的值就默认为设置的那一个属性的值。
2)所以jsp为了支持中文,以上两个属性至少要设置一个。
2>page指令的import属性:
import属性的本质就是jsp页面对应的Servlet中的import关键字导包。
import属性是唯一可以重复出现的属性,如:
<%@ page import = "java.util.*" import = "java.io.*"%>,还可以使用“,”分隔
<%@ page import="java.util.*,java.io.*"%>,但是一般会使用多个page指
令来导入多个包:
<%@ page import="java.util.*"%>
<%@ page import="java.io.*"%>
3>page指令的errorPage属性和isErrorPage属性:
1)errorPage属性:我们知道,当请求的jsp页面出错抛出异常后,服务器会给浏览器响应错误信息
那么就可以使用page指令的errorPage属性来自定义错误页面。如:
<%@ page errorPage ="xxx.jsp"%>,那么当前jsp页面出错时,就会请求转发到xxx.jsp,并且响应
200状态码,表示请求成功。
2)isErrorPage属性:如果希望给客户端响应的状态码为500,那么就还需要使用isErrorPage属性指定
通过errorPage属性请求转发的jsp页面为错误页面。当isErrorPage属性的值为True时,说明当前jsp
页面为错误页面,即专门处理错误的页面,那么在这个jsp页面中就可以使用内置对象exception了,
其它的页面时不能使用exception内置对象的。
3)web.xml中也可以配置错误页面
使用jsp的page指令的errorPage属性和isErrorPage属性可以配置错误页面,还可以在web.xml
中配置错误页面。
<!--
服务器给客户端响应404状态码,即客户端访问的资源不存在时,请求转发到error404.jsp页面
-->
<error-page>
<error-code>404</error-code>
<location>/error/error404.jsp</location>
</error-page>
<!--
服务器给客户端浏览器响应500状态码,即客户端请求服务器的资源出错抛出
异常时,请求转发到error500.jsp页面
-->
<error-page>
<error-code>500</error-code>
<location>/error/error500.jsp</location>
</error-page>
<!--
上面的配置表示,当服务器响应500状态码,即客户端请求服务器的资源出错
抛出异常时,请求转发到指定页面,而500状态码表示的是服务器资源抛出任何
异常.如果需要指定对具体的异常进行处理的话就使用以下配置,表示当请求的
服务器资源抛出空指针异常时,就请求转发到nullPoint.jsp
-->
<error-page>
<exception-type>java.lang.NullPointerException</exception-type>
<location>/error/nullPoint.jsp</location>
</error-page>
4>page指令的autoFlush属性和buffer属性
1)buffer属性:表示当前jsp的输出流(out内置对象)的缓冲区大小,默认为8KB.
(一般不需要修改)
2)autoFlush属性:指定当前jsp的输出流(out内置对象)缓冲区满时,是否自动刷新。
默认为true,自动刷新,表示当缓冲区满时自动把缓冲区数据输出到客户端。
如果改为false时,那么在缓冲区满时抛出异常。(一般也不需要修改)
5>page指令的isELlgnored属性:
表示当前jsp是否忽略EL表达式,默认值为false,表示不忽略,即支持。
(一般不需要修改)
6>page指令一些基本没用的属性:
1)language属性:指定当前jsp编译后的语言类型,默认值为java。(目前只支持java)
2)info属性:当前jsp的说明信息
3)isThreadSafe属性:当前jsp是否支持并发访问,默认值为true,支持。当改为false时,
jsp生成的servlet会去实现一个过时的标记接口SingleThreadModel,这时jsp就只能单线程访问。
(一般不需要修改)
“ isThreadSafe ”是14个属性页面指令支持之一。此属性采用布尔值true或false,表示JSP页面在多线程环境中是否安全。默认值是true。
isThreadSafe JSP的语法
<%@ page isThreadSafe =“true”%>
设置为true时,相同的JSP页面可以支持多个客户端。这是什么意思?为了更好地理解,我通过Servlet解释,因为JSP文件在内部转换为Servlet。当客户端请求JSP文件时,容器会加载JSP文件,将其转换为Servlet,然后编译然后执行。对于多个客户端的请求,容器也会创建相同Servlet的多个对象。对于每个Servlet对象,都会创建一个单独的service()方法。也就是说,每个客户端都有一个单独的service()方法。因此,Servlet和JSP是隐式线程安全的。
那么当Servlets和JSP自动进行线程安全时,isThreadSafe =“false”的含义是什么?
如果Programmer 只想为Servlet / JSP 创建一个对象(而不是多个对象),那么声明为false。也就是说,多个客户端请求相同的JSP(或Servlet),加载并执行相同JSP的多个文件。这会降低性能。当数据非常重要且像银行汇款业务或者军事绝密数据等非常重要时,需要进行此类型编码。需要几个servlet相互影响的时候
概要:
1. isThreadSafe =“true”,在多个客户端请求时为同一个JSP文件创建多个对象。每个客户端都有一个单独的_jspService()方法(只加载了一个JSP文件)。
2. isThreadSafe =“false”,允许容器为请求相同JSP的每个客户端创建一个Servlet对象。多个客户端将拥有容器创建的多个Servlet对象,以支持所有客户端。
这是使用SingleThreadModel接口在Servlet中实现的。
4)session属性:当前jsp页面是否支持session,默认为true,表示当前jsp可使用内置对象
session;如果改为false,表示当前jsp不能使用内置对象session(一般不需要修改)
5)extends属性:让当前jsp生成的servlet去继承该属性指定的类。(一般不需要修改)
2、include指令:
include指令表示静态包含,其目的是把多个jsp合并成一个jsp;
include指令只有一个属性file,指定所包含的页面,如:<%@ include file = x.jsp"%>
include指令静态包含reuqest.getRequestDispacher().include()的请求包含的功能相似,但是
1>request.getRequestDispatcher().include()是请求包含,包含和被包含的是两个servlet,即
两个.class,只是把两个servlet的响应内容在运行时合并了,再统一
响应给客户端。
2>include指令是在jsp编译成java文件时完成的。它是把两个jsp合并成一个jsp然后编译成一个java
文件(也就是一个servlet),最终生成一个class文件
在jsp页面被编译成java文件之前,还是jsp的时候就合并了。
注意:include指令静态包含,包含页面和被包含页面不能出现相同内容部分,
因为两个jsp页面会被合并成一个jsp,进而再被编译成一个servlet,
不可能出现重复定义内容。
应用:把页面分解了,使用include指令组合在一起。页面中不变的且重复使用的部分就是一个独立的jsp
而我们只需要处理变化的页面部分。
3、taglib指令:
在jsp页面中使用第三方标签库时,需要使用taglib指令来导入标签库。两个属性:
1>prefix:指定标签库在当前jsp页面使用的前缀。
自定义命名,类似于xml的名称空间。
2>uri:指定标签库的位置。一般是由第三方标签库定义好的。
3>指定标签库的标签的使用:<前缀:标签名>
如:<%@ taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core" %>
使用该标签库的text标签时,是<c:text>
二、jsp的九大内置对象:
每个jsp页面服务器都会将其编译成对应的一个.java(即一个servlet)文件,
而jsp页面的内容的“真身”在对应的servlet的jspService()方法中,
而在jspService()方法的开头部分已经创建了九大内置对象,
所以在jsp页面可以直接使用这九大内置对象。
1、out:是JspWriter的对象,等同于servlet的PrintWriter out = response.getWriter();
获取的PrintWriter的对象,作用就是向客户端响应输出文本数据。
2、config:他就是ServletConfig的对象。在servlet中ServletConfig对象就代表当前
<servlet>
<servlet-name></servlet-name>
<servlet-class></servlet-class>
</servlet>
的内容
而jsp我们不需要在web.xml中配置,所以config内置对象在jsp中几乎没用。
3、page:当前jsp对象(this),但其在jsp编译的servlet中是以
Object page = this;
存在的,属于多态思想,所以子类对象this的很多属性和功能父类引用page都无法使用。
而在jsp的<%%>java脚本中能直接用this去操作当前jsp对象绝不用page,
所以page内置对象在jsp中也几乎不用。
4、exception:异常对象,只有在错误页面中才可以使用该对象。
5、request:HttpServletRequest的对象,请求对象。
6、response:HttpServletResponse的对象,响应对象。
7、application:ServletContext的对象,服务器会为每个web应用程序创建唯一的
一个ServletContext对象,其作用就是在整个web应用的动态资源之间共享数据,即多个servlet
和jsp之间就都可以通过获取这个唯一的ServletContext对象来传递数据。
8、session:HttpSession的对象,服务器会为每个会话创建一个session对象,多个动态资源
即多个servlet和jsp就可以使用session对象在同一会话中共享数据。
9、pageContext对象:域对象
在javaWeb中一共有四大域对象,其中servlet中可以使用request、session、ServletContext
三个对象,在jsp中可以使用pageContext、request、session、application(ServletContext)
四大域对象:
1>application(ServletContext):在整个web应用中共享数据
2>session:在一个会话中共享数据
3>request:在一个请求链中共享数据
4>pageContext:在一个jsp页面中共享数据。这个域是指在当前jsp页面和当前jsp页面中使用
的标签之间共享数据。
1>pageContext域对象功能:
pageContext域对象是四个域对象中范围最小的,在当前jsp页面和当前jsp页面中使用的标签之间
共享数据:
1>void | setAttribute(String name,Object value)
2>Object | getAttribute(String name)
3>void | removeAttribute(String name)
2>pageContext获取其它内置对象:
拿到了pageContext内置对象就等同于拿到了所有的内置对象,因为pageContext对象
可以获取其它8个内置对象:
1>JspWriter | getOut()获取out内置对象
2>ServletConfig | getServletConfig()获取config内置对象
3>Object | getPage()获取page内置对象
4>ServletRequest | getRequest()获取request内置对象
5>ServletResponse | getResponse()获取response内置对象
6>HttpSession | getSession()获取session内置对象
7>Throwable | getException()获取exception内置对象
8>ServletContext | getServletContext()获取application内置对象
3>pageContext代理其他域对象
因为pageContext对象可以拿到其它8个内置对象,所以可以使用pageContext域对象
来代理其它3个域对象,也就是说可以使用pageContext对象向request、session、
application域对象中存储数据和获取数据。
1>void | setAttribute(String name,Object value,int scope)向指定的域对象中添加数据
2>Object | getAttribute(String name,int scope)从指定的域对象中获取数据
3>void | removeAttribute(String name,int scope)移除指定域对象中的数据
如:
1>pageContext.setAttribute("uname","mmy");默认向pageContext域中存储数据
2>pageContext.setAttribute("uname","mmy",PageContext.REQUEST_SCOPE)向
request域对象中存储数据
3>pageContext.setAttribute("uname","mmy",PageContext.SESSION_SCOPE)向
session域对象中存储数据
4>pageContext.setAttribute("uname","mmy",PageContext.APPLICATION_SCOPE)向
application域对象中存储数据
4>全域查找
pageContext全域查找:Object | findAttribute(String name)
1>会从小到大,依次在pageContext,request,session,
application域对象中查找名为name的数据的值,如果找到则返回结果,没有则返回null。
2>如果在在多个域对象中存在同名的属性,那么依据优先级别,范围最小的域对象的优先
级别最高。所以存储同名的属性时,为了进行区别都加上前缀,如:
pageContext.setAttribute("uname","mmy");
pageContext.setAttribute("request_uname","mmy",PageContext.REQUEST_SCOPE)
pageContext.setAttribute("session_uname","mmy",PageContext.SESSION_SCOPE) pageContext.setAttribute("application_uname","mmy",PageContext.APPLICATION_SCOPE)
三、jsp的动作标签:
1>jsp的动作标签的作用是用来简化java脚本的,因为其内部封装的就是java脚本。
2>jsp的动作标签和html的标签的区别:
A>html的标签是由浏览器来解析执行的。
B>jsp的动作标签它封装的就是java代码,和java代码一样都是由服务器解析执行的。
3>jsp动作标签的格式:<jsp:标签名>
4>jsp的动作标签是javaWeb内置已经定义好的动作标签,供于我们直接使用。
1><jsp:forward>动作标签:
<jsp:forward>动作标签的作用就是请求转发,和
servlet的request.getRequestDispatcher("").forward(request, response);
的作用是一样的。
2><jsp:include>动作标签:
<jsp:include>动作标签的作用就是请求包含,和
servlet的request.getRequestDispatcher("").include(request,response);
的作用是一样的。
<jsp:include>动作标签和<%@include%>指令的区别:
1><%@include%>能够是静态包含,是指在两个jsp页面在被编译成servlet之前,
合并成一个jsp页面,然后在被编译成一个servlet。
2><jsp:include>动作标签,也叫动态包含,它于servlet的request.getRequestDispatcher("").include
(request,response);
一样都是请求包含的作用。即表示当前jsp和被包含的jsp页面都被编译成各自对应的servlet后,在运
行时当前jsp页面时请求包含到被包含的jsp页面,合并两个jsp页面的响应体,共同向浏览器完成
完整的一个响应。
3><jsp:param>动作标签:
还可以在<jsp:forward>和<jsp:include>动作标签之间使用<jsp:param>动作标签,向被请求转发和
请求包含的jsp页面传递参数。
<jsp:forword page="b.jsp">
<jsp:param name="uname" value="aaa"/>
</jsp:forword>
等价于:
request.getRequestDispatcher("/b.jsp?uname=aaa").forword(request,response);
4<jsp:useBean>如果javaBean对象存在,则从指定域对象中获取javaBean对象;
如果不存在,在当前jsp页面创建javaBean对象,并保存到指定域对象中。
默认域对象时pageContext,
可以使用scope属性来指定保存到的域对象,或指定获取javaBean的域对象
5><jsp:setProperty>和<jsp:getProperty>
<jsp:setProperty>标签的作用是给指定的javaBean对象的javaBean属性赋值,
<jsp:getProperty>标签时获取指定javaBean对象的javaBean属性的值: