JSP的内置对象
什么是JSP的内置对象呢?
在JSP页面进行编程的时候,如果我们要使用一些对象,如:HttpSession,ServletConfig,ServletContext这些对象,如果每次都要先创建这些对象,然后再去使用它们,这样就显得十分繁琐了,为了方便使用者,Sun公司在开发JSP的时候,把一些对象设置为内置对象,开发者在JSP页面编程的时候不必声明这些对象就能直接使用,这就是JSP的内置对象。
那么JSP对象有哪些呢?
JSP内置对象 对应的类型 备注
Request HttpServletRequest 用于得到请求信息
Response HttpServletResponse 用于设置响应信息
Application ServletContext 代表web应用环境
Config ServletConfig 用于得到Servlet初始化参数
Session HttpSession 用于的设置Session对象,调用request.getSession时被创建
Page Object 在JSP被翻译成java文件后,创建的字节码对象
Out JspWriter 一个带缓冲的PrintWriter
Exception Thorwable 异常对象,封装异常信息,发生异常时调用
Pagecontext PageContext 代表当前jsp的上下文对象
上面大多数对象在学习Servlet的时候已经学习过,下面我们只说一下两个特别的对象:
Out对象
Out对象的类型:JspWriter ,用于向浏览器输出数据。
我们知道以前向页面输出数据,要用到PrintWriter,下面说一下两者的区别:
PrintWriter:直接向页面输出数据,通过调用它的write()方法。
JspWriter:内部有一个一定大小的缓冲区,当这个缓冲区满了,先把缓存区的数据写入 PrintWriter,然后由PrintWriter把数据输出到页面。
那如果要输出的数据填不满缓冲区怎么办呢,别担心,开发者已经为我们想好了:
JspWriter把数据写入PrintWriter的情况:
1)缓冲区满了。
2)Jsp页面已经加载完成,缓冲区虽然没有满,但JspWriter会把数据写入PrintWriter。
3)关闭JspWriter的缓冲区,JspWriter就会把数据直接写入PrintWriter。
那我们怎么设置缓冲区的大小呢?
我们可以在jsp页面使用page指令,然后设置它里面的buffer属性。
如果不设置,它的默认值是8kb。如果想关闭缓冲区我们可以把缓冲区的大小设置为 0kb或none。
PageContext对象
Pagecontext对象的数据类型:PageContext。
作用:代表当前jsp上下文对象。
那么什么是上下文对象呢?在语文书我们可能看到这样的语句:“根据上下文,xxxxxxx”
所谓的上下文就是全文,所以Pagecontext对象可以获取jsp的全部内置对象~
1)通过pagecontext对象来获得jsp的其他8个内置对象
代码如下:
<body> <% pageContext.getRequest(); pageContext.getResponse(); pageContext.getSession(); pageContext.getException(); pageContext.getOut(); pageContext.getPage(); pageContext.getServletConfig(); pageContext.getServletContext(); %> </body>
为什么它可以这样获取其它内置对象呢?我们来看看它的源代码吧~
class _04_page_jsp extends HttpServlet{ public void _jspService(){ PageContext pageContext;//把8个内置对象放入PageContext类中 HttpSession session; ServietConfig config; SevletContext application; ..... //调用method1 method1(pageContext); } public void metdho1(PageContext pageContext){ //在这里需要使用到内置对象。例如session、config...... //得到pageContext对象就可以得到其他8个内置对象 pageContext.getRquet(); pageContext.getResponse(); ........ } }
由上述代码可以看到,在JSP类里面的Serive()方法内声明了这些变量,而里面又调用了了method1方法了把8个内置对象add到pageContext里了~
除了这个作用,pageContext还能作为域对象来使用。
1)pageContext作为域对象使用
域对象的作用:保存数据,得到数据
我们之前已经学过三个域对象:
requset域对象
context域对象
session域对象
这些都是servlet里可以使用的域对象。
然而,在JSP中,除了可以使用上面的三个域对象,还能使用pageContext域对象。
pageContext域对象的范围: 在当前jsp页面中有效的!!!
那么现在我们来使用它吧~
你可以这样把数据保存到pageContext域
pageContext.setAttribute("name",Object);
然后这样得到数据:
pageContext.getAttribute("name");
除了可以把数据保存在pageContext域,你也可以用pageContext对象把数据保存在其它域对象里!
指定域对象保存:
pageContext.setAttribute("name",Object,域常量)
指定域获取:
pageContext.getAttribute("name" ,域常量);
域常量:
PAGE_SCOPE: pageContext域
REQUEST_SCOPE: request域
SESSION_SCOPE: session域
APPLICATION_SCOPE: context域
自动搜索:
pageContext.findAttribute("name");
注意:自动在4个域中依次按顺序(从小到大)搜索数据:
page -> requeste -> session -> application
如果在某个域中找到数据,则返回该域中的数据,如果4个域都找不到数据,那么就返回null
总结4个域对象
1.jsp的4个域对象
a) Request
b) Session
c) Application
d) pageContext
2.域对象的作用
保存数据,得到数据,清楚数据
3.域对象的核心方法
setattribute(String s,Object obj);
getattribute(String s)
removeattribute(String s)
4.四个域对象的作用范围
Request域对象:同一次请求有效,可用转发来维持。
Session域对象:同一次会话有效。
Application域对象:同一个web应用下有效。
pageContext域对象:同一个jsp页面内有效。
可以在html页面内嵌入java代码,这样是十分不利于开发者和美工分工的,所以后来我们提倡:尽量在jsp页面内不使用java代码,为此,两种新的技术出现了:
我们 用EL表达式来代替 jsp表达式;
用jsp标签来代替jsp中的java脚本。
EL表达式
那么什么是EL表达式
Jsp中的一种语法,用来代替jsp表达式。
EL表达式的语法:
${变量或表达式} 十分的简便。
EL表达式的用法!
1)用与输出域中的数据
我们现在两个域中存入名字一样的两个数据,然后用EL来输出到页面
pageContext.setAttribute("id", "rrrr",pageContext.REQUEST_SCOPE); pageContext.setAttribute("id", "ppp"); %> ${id}
页面输出的结果为:ppp
所以,如果没有指定域对象,EL表达式就会依次在page->request->session->application域里找那个名字的变量,先找到就先用。
那么如何指定域对象呢??在变量名前加上域范围!
${域范围.name}
域范围:
pageScoope: pageContext域
requestScope: request域
sessinoScope: session域
applicatinScope: application域
1)除了能输出域对象保存的数据,EL表达式还能输出对象里的属性!!!
假如我们定义了一个Person类,它有一个属性name,有一个getName()方法。
那么我们可以用EL表达式来把它的name属性的值取出来:
pageContext.setAttribute("person", person); %> ${person.name}
这样就能把name属性的值取出来了!为什么会这样呢,因为EL表达式中的 .name 相当于调用了对象的getName()方法,这一点大家要注意了。
1)EL表达式也可以用来输出集合对象的值!
List对象:
pageContext.setAttribute("personList", list); %> ${personList[0]}
中括号里的值表示脚标!是不是很简便~
Map对象:
pageContext.setAttribute("personMap", map); %> ${personMap["ppp"]}
中括号里填的是key的值,这样就能得到对应的value的值了~
4)用于计算表达式
算术、${12+13-12*5+100}
比较、${5<3}
逻辑、${5<6&&7>8}
判空 判断是否null${name==null }
判断是否是空字符串${name==""}
还有一种empty关键字可以用来判断空和null,用法:
${empty name }
EL表达式内置对象
EL表达式还有内置对象!!别怕,很多都学过了,分别是
pageContext --等价于jsp的pageContext内置对象
pageScope --指定域获取
requestScope
sessionScope
applicationScope
param --请求参数
paramValues
header --请求头
headerValues
除了以上9种内置对象,还乐意获得以下两种~
cookie --获取cookie
initParm --获取web应用全局参数
下面用代码示范一下:
<body> <%=pageContext.getRequest() %> <br/> <%--EL获取web上下文 --%> ${pageContext.request.contextPath } <br/> ${pageContext.request.remoteHost } <a href="${pageContext.request.contextPath }/04.el1.jsp">页面</a> <hr/> <%-- param / paramValues --%> <%--jsp接收参数 --%> <% String name = request.getParameter("name"); //out.write(name); String[] names = request.getParameterValues("name"); for(String n:names){ out.write(n+"<br/>"); } %> <%--EL获取参数 --%> <br/> EL: ${param["name"]}<br/> EL: ${paramValues["name"][0] } - ${paramValues["name"][1] } <hr/> <%--请求有: header / headerValues --%> <%--jsp获取头 --%> <%=request.getHeader("user-agent") %> <%=request.getHeaders("user-agent") %> <br/> <%--EL获取请求头 --%> EL: ${header["user-agent"] }<br/> EL: ${headerValues["user-agent"][0] } <hr/> <%--cookie: --%> <%--jsp获取cookie --%> <%=request.getCookies() %> <br/> <%--EL获取 Cookie--%> ${cookie["JSESSIONID"].name } - ${cookie["JSESSIONID"].value } <hr/> <%--EL获取全局参数--%> ${initParam["AAA"] } - ${initParam["BBB"] } </body>
以上就是EL的内容,重点在引用属性时会调用它的getXxxx方法!
下面我们来说一下JSP的标签吧!
Jsp标签
聪明的你一定会发觉,就算EL表达式可以代替JSP表达式,但想要完成一些功能,EL表达式是不够的,例如循环,条件判断等。所以JSP标签就来和它相辅相成了!
什么是JSP标签
jsp标签 替代 jsp脚本的功能。
Jsp标签分类
一)JSP内置标签,又称为动作标签
二)JSTL标签库的标签
三)自定义标签
就三种,不多~
动作标签
动作标签不用手动导入,所以我们直接使用就行。常使用的动作标签有以下三种:
<jsp:forward page=""> 转发标签
<jsp:param name="" value=""/> 参数标签。参数标签不能单独使用,只能用在forward或include 标签中。
<jsp:include page=""/> 包含标签。用于包含其他页面。是一种动态包含。
那么现在在JSP文件中演示下吧:
<jsp:include page="包含的页面"> <jsp:param name="参数名" value="参数值"/> </jsp:include> <jsp:forward page="页面名称"> <jsp:param name="参数名" value="参数值"/> </jsp:forward>
什么是动态包含呢?
JSP文件需要先翻译成JAVA源文件,然后再编译成CLASS文件。
动态包含:两个JSP文件各自先翻译,然后在编译运行时再合并。也就是说途中会产生多个java文件
静态包含:两个文件先合并,然后一并翻译成java源文件,过程中只产生1个java文件。
***************静态包含 vs 动态包含*****************
静态包含: @include指令实现。原理是先合并再翻译。静态包含不能携带参数。
动态包含: <jsp:include/> 标签实现。原理是先翻译再合并。动态包含可以使用<jsp:param/>标签携带参数到被包含页面
JSTL标签库
JSTL,Java Strandard Tag Libarary java标准标签库
*****使用jstl标签库,需要在jsp页面中导入标签库
常见的JSTL标签库
核心标签库 (c: 设置变量,获取变量,条件判断,循环 )(主要)
国际化标签库 (fmt: 日期国家化,文字国际化,数字国际化 )(以后说)
EL函数库 ( fn:对String常用的方法 )
数据库标签库 (sql:对数据库操作的标签)
XML标签库( x:对xml文件操作的标签 )
核心标签库
使用jstl标签步骤:
1) 如果是用java5.0的jar包,那么就已经包含jstl的jar包。
2) 在jsp页面头部导入标签库:
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
3)在jsp页面中使用
核心库中常用的几种标签
<c:set></c:set> -- 设置数据
<c:out value=""></c:out> --得到数据
<c:if test=""></c:if> --单条件判断
<c:choose></c:choose> --多条件判断
<c:when test=""></c:when>
<c:otherwise></c:otherwise>
<c:forEach></c:forEach> --循环,遍历集合或数组
<c:forTokens items="" delims=""></c:forTokens> -循环字符串
<c:redirect></c:redirect> --重定向
下面我们来一一示范下怎么使用这些标签吧
<body> <%--使用set标签设置数据,默认是在pageContext域中设置,也可以指定域保存 --%> <c:set var="name" value="eric" scope="request"></c:set> ${requestScope.name} <%-- out标签,从域对象中得到数据, default属性:设置默认值,当属性为null时,就会用默认值代替 escapeXml:是否对内容进行转义,false:不进行转义,true:进行转义 什么是转义:特殊字符不会被识别作用,当普通字符输出 --%> <c:out value="${name}" default="abc" escapeXml="false"></c:out> <%--if标签:单条间判断--%> <c:if test="${1>2}"> 条件成立执行的内容 </c:if> <%--choose标签:多条件判断 --%> <c:set var="id" value="001"></c:set> <c:choose> <c:when test="${id=002}">此用户是002</c:when> <c:when test="${id=001}">此用户是001</c:when> <c:otherwise>不存在此用户</c:otherwise> </c:choose> <%--遍历List begin:从哪个元素开始遍历,第一个下标为0 end:到哪个元素结束 step:步长 items:需要遍历的对象的名称 var:每个元素对象的名称 varStatus:当前遍历对象的状态,即:已经遍历了几个元素。 --%> <c:forEach items="${list}" var="student" varStatus="varSta"> 序号${varSta.count}-姓名${student.name}-年龄${student.age} </c:forEach> <%--遍历Map--%> <c:forEach items="${map}" var="entry" varStatus="varSta"> 序号${varSta.count}-编号${entry.key}-姓名${entry.value.name} </c:forEach> <%--forTokens便签 :循环字符串,可以切割后将子串都输出 items:要循环的对象 delims:以什么东西切割字符串 var:切割后的单个对象的名称 --%> <c:forTokens items="${str}" delims="-" var="s"> ${s} <br/> </c:forTokens> <%--重定向 标签--%> <c:redirect url="http://www.baidu.com"></c:redirect> </body>