北京行——JSP、EL、JSTL精通
JSP 技术
day8 JSP语法 + EL + JSTL
day9 案例 2-3 个 综合小案例
day10 Servlet+JSP 综合练习
为什么sun推出 JSP技术 ?
Servlet 生成网页比较复杂,本身不支持HTML语法,html代码需要通过response输出流输出,JSP支持HTML语
法,生成HTML方便。
JSP技术与Servlet 技术区别和关系?
JSP和Servlet技术都是用来动态生成网页的,Servlet不支持HTML语法,生成网页麻烦,JSP支持HTML语法,
生成网页方便,JSP运行时翻译Servlet 执行的。JSP 就是 Servlet 。
JSP运行原理是怎样的 ?
客户端访问编写JSP文件,服务器读取JSP文件,根据JSP生成Servlet ,Servlet编译运行 生成网页。
JSP <%! %> <%= %> <% %>
<%! %> 声明:定义翻译后Servlet程序的 全局变量或全局方法、内部类
<%= %> 表达式 输出内容到浏览器 效果out.print
<% %> 脚本代码块,嵌入java运行代码 ---- 不翻译
JSP翻译Servlet 存放tomcat/work 目录
* JSP翻译Servlet 页面当前所有HTML 翻译为 out.write 输出
JSP的注释 支持三种注释
1、JSP注释 <%-- --%> 只存在JSP文件源码中,在JSP翻译Servlet时,这类注释消失了
* 该类注释得不到执行
2、Java注释 /** */文档注释 /* */多行注释 // 单行注释
文档注释 /** */ 生成javadoc 主要用来注释 包、类、成员变量、成员方法 ------ 代码功能使用者
多行注释 和 单行注释 不会生成javadoc,注释代码实现逻辑 用于在方法内 ------ 程序员本身,读懂代
码进行注释
* Java注释 在JSP翻译为Servlet时存在,在Servlet程序执行时,会被忽略,生成HTML网页源代码中不存在
* 在Servlet执行过程中被忽略
3、HTML注释 <!-- -->
* 在JSP翻译为Servlet时 会被翻译 out.print 在生成HTML页面源代码中该类注释 也是存在的
结论:JSP注释在翻译阶段消失,Java注释在Servlet运行阶段消失,HTML注释不消失
思考题:
<%
String s = "abcd";
%>
<!-- 用HTML注释 注释 JSP或者java代码 <%=s%> -->
在页面结果中 <!-- 用HTML注释 注释 JSP或者java代码 abcd -->
结论: HTML注释 无法阻止 JSP或者 Java代码执行的
JSP 指令 (JSP Directive)
page指令
include指令
taglib 指令
语法:<%@ 指令名称 属性=值 属性=值 ... %>
page指令用来定义JSP文件的全局属性 <% page 属性=值 %>
1、language 只能为java
2、extends JSP翻译后Servlet 继承父类,这个属性一般不设置 ,如果非要设置,继承类必须是Servlet实
现类
3、session 定义JSP中是否可以直接使用Session隐含对象
如果属性设置为true在JSP翻译Servlet时 生成以下两句代码
HttpSession session = null;
session = pageContext.getSession();
* 如果jsp中想使用HttpSession对象,使用session属性默认值true
4、import 完成 JSP翻译后 Servlet 导包
jsp在翻译为Servlet 默认导包
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
jre默认导入 java.lang
* 在jsp中如果使用类 不属于以上四个包,需要导包
5、buffer autoFlush 设置 out隐含对象属性
buffer 设置缓冲区大小
autoFlush 设置当缓冲区满后,自动刷出
6、isELIgnored 设置JSP是否执行EL表达式
isELIgnored="false" 不忽略---执行解析
isELIgnored="true" 忽略 ---- 不解析
* 一般就是默认值false
7、通过contentType和pageEncoding 设置 JSP页面编码
pageEncoding 是 JSP文件源代码在硬盘上编码集
contentType 在Servlet生成HTML 传递浏览器采用编码
在内存中的字符时没有编码的,unicode,为什么要有编码,是因为要将内存中的编码,写成字符串,这时候才需要编码
8、通过errorPage 和 isErrorPage 控制 JSP页面发生错误时跳转
设置错误友好页面 ---- 当页面发生错误,不应该给用户看到含有代码错误页面,看到一个友好页面
通过errorPage指定 在页面发生错误跳转到哪个页面 ,这个非常不错
* IE 浏览器默认好友页面 ,如果想看到自己编写友好页面,关闭IE默认友好页面
IE 工具栏 --- Internet选项 ----- 高级 -----显示友好HTTP错误信息 将钩去掉
在错误友好页面中,可以通过设置isErrorPage属性,获得错误原因
*在实际开发中,一般不使用上面讲解错误处理方式
错误页面第二种处理方式: 不仅可以处理500 ,还可以处理404
配置web.xml
<error-page>
<error-code>500</error-code>
<location>/demo5/500.jsp</location>
</error-page>
这个是重要的方法
include指令 ,用来静态包含页面 ----- 将页面公共部分提取出来,通过include完成页面布局
语法:<%@ include file="文件路径" %>
include包含目标页面整个内容,被包含页面,不需要是一个完整HTML,只要编写HTML片段就可以了
静态include 原理
*在 JSP翻译为Servlet时,完成包含动作,Servlet程序并没有执行,包含路径不能用变量、不能含有?拼接
参数,目标文件必须存在
* 存在特殊案例:被包含页面存在错误,只要包含后Servlet没有错误,就可以执行
这个是合并后的结果只要正确就行,也就是说让他们成为一个文件
taglib指令 ,用来在jsp页面引用标签库文件
* 定义标签作用为了简化 jsp页面开发
* 通过taglib 指令引入 jstl标签库 ,语法: <%taglib uri="" prefix="" %>
uri ---- 定义标签 唯一命名空间
prefixt ---- 命名空间前缀
引用jstl时,在导入jstl.jar中 META-INF/c.tld
<short-name>c</short-name> -------- 就是prefix属性
<uri>http://java.sun.com/jsp/jstl/core</uri> ----- 就是uri属性
JSP的九个内置对象分别是什么?JSP中最重要的问题
什么是内置对象? JSP翻译为Servlet代码时,有些对象默认已经创建好的,这类对象可以直接在jsp中使用
,内置对象
page、request、session、application(四个范围)、response、pageContext、out、config、exception(设置错误属性)
request HttpServletRequest ---- 请求对象
response HttpServletResponse ---- 响应对象
session HttpSession ------- 会话对象
application ServletContext ------ web应用全局唯一对象,这就是唯一的一个全局变量
config ServletConfig ------ 初始化数据
page this (HttpServlet)---------------当前页面
pageContext PageContext
exception Throwable (所有异常父类) ----- 当页面是一个错误页面,用exception获得异
常信息
一个页面中默认有8个内置对象,iserror打开才有
* Throwable 是 exception 类 父类
out JspWriter
page 代表当前jsp生成Servlet对象
* page 是 Object类型,只能使用Object中方法 ---- 这个对象在开发中不建议 使用
* 可以将page强制转换 HttpServlet对象的
Servlet有几种数据范围? 三种: request、session、servletcontext
JSP 在 Servlet三种数据范围基础上,新添加page数据范围 ---- JSP 四种数据范围: page request
session application
* page数据范围存放数据 只在当前jsp内有效
pageContext代表当前页面上下文
1、向page范围存取数据
findAttribute 依次在 page 、request 、session 、 application 四个数据范围进行数据查找
EL 中 ${name} 调用 findAttribute 在四个范围中依次查找数据
2、pageContext 用来 获得其它八个隐含对象
* pageContext封装八个隐含对象意义:框架编写减少参数的使用,得到PageContext对象 相当于得到 JSP九个内置对象
out对象
out功能向浏览器输出信息,是JspWriter类型,内部使用PrintWriter实现,拥有独立缓冲区。
out创建 ,out对象通过pageContext对象获得,创建pageContext对象时,指定out缓冲区大小以及是否自动
flush
* 通过 page指令 buffer autoFlush 设置out 缓存区大小 以及是否自动 flush
out向浏览器输出内容,response.getWriter 向浏览器输出内容 , 区别?
out.println("aaa");
response.getWriter().println("bbb");
out.print("ccc");,
response.getWriter输出内容,在out输出内容之前?
out必须通过response进行回写,浏览器只对一个有反应就是response
page request session application response out config pageContext exception
JSP指令和JSP标签 区分?
JSP 指令 Directive
JSP 标签 Action
jsp中六个动作标签
<jsp:useBean> <jsp:setProperty> <jsp:getProperty> ----- 与 JavaBean操作相关 明天学习
<jsp:include> <jsp:forward> <jsp:param >
<jsp:include> 效果 等价于 request.getRequestDispatcher().include
<jsp:forward> 效果 等价于 request.getRequestDispatcher().forward
<jsp:include> 标签 功能 等价于 <%@ include %>
原理:动态包含
语法:<jsp:include page="文件路径" />
被包含页面不需要完整html,只需要编写html片段
jsp:include 和 @include 区别
@include include指令, 静态包含,在jsp翻译为Servlet时,执行包含动作,包含结果是目标页面翻译
Servlet源代码 ,翻译为一个Servlet一起执行
jsp include 标签,动态包含, 在index servlet执行时 完成包含动作,包含结果是目标jsp翻译Servlet生
成 html页面结果,每个被包含jsp翻译单独Servlet进行执行
<jsp:forward page="/demo11/b.jsp"></jsp:forward> 等价于 request.getRequestDispatcher
("/demo11/b.jsp").forward(request,response);
<jsp:forward page="/demo11/b.jsp">
<jsp:param value="itcast" name="name"/>
</jsp:forward>
上面写法用jsp传递一个参数,用jsp如果向传递参数,直接通过setAttribute
EL 表达式语言,来自民间 ,Servlet2.4 之后 EL 被纳入官方规范
功能:
1、EL 获得 JSP四个范围中保存数据 (访问JavaBean的属性)
2、EL 表达式支持运算
3、EL 内置 11个对象 --- web开发常用对象
4、EL 调用 java的方法
EL是从javaee1.4版本才被纳入规范,javaee1.3 及以前版本,默认对EL不进行解析
* 如果想 javaee1.3 以及之前版本解析 EL ------ 设置 page 属性 isELIgnored = false
1、使用EL 获得 jsp四个范围数据
附代码:
使用EL指定查找四个范围数据 ${pageScope.属性名称} ${requestScope.属性名称} ${sessionScope.属性名
称} ${applicationScope.属性名}
如果不执定查找数据范围 ${属性名称} ---- 调用pageContext.findAttribute 在四个范围依次查找
如果查找属性不存在,返回是一个 "" 空串,而不是null
获得数组、List、Map时 有些情况使用 [] 获得属性值
. 和 [] 有什么区别 ?
答案:. 和 [] 都可以用来取得EL 属性值,.可以实现功能 [] 都可以!
例如: ${pageScope.user.name} 也可以写为 ${pageScope.user["name"]} (获得对象后,访问对象属性时
才可以用 [] 取代.效果 )
[] 可以使用特殊标识信息,但是. 不可以
例如:
pageContext.setAttribute("0","itcast");
pageContext.setAttribute("aa.bb","春生泰克");
只能通过[] 进行访问 ----- 注意:在使用[] 进行属性取值时,加"" , 不加"" 认为是一个变量
在使用EL进行取值时,如果含有特使字符属性,尽量使用[] , 否则都使用. 就可以了
2、在EL 中执行 算术、比较、逻辑运算
在EL 执行运算时,运算语句必须写入 ${}中
* 在EL 获得属性值 执行算术运算,自动类型转换 ---- 执行算术运算时,进行运算参数,必须都是数字
${"a"+"b"} ---- 发生数字格式化错误
empty运算符
1) 判断一个属性是否存在 , 通常empty运算符都是结合c:if 一起使用
2) 使用empty 判断List 或者 Map是否为空 (size==0)
二元表达式:${user!=null?user.name:""} ----- 三元运算符
3、EL 11个内置对象
pageScope requestScope sessionScope applicationScope 四个数据范围,用来取值
pageContext 当前jsp上下文 ----- ${pageContext.request.contextPath }
${param.name} 等价于 request.getParameter("name")
${paramValues.hobby} 等价于 request.getParameterValues("hobby")
${header.referer} 等价于 request.getHeader("referer")
${headerValues["Accept-Encoding"]} 等价于 request.getHeaders("Accept-Encoding")
${initParam.name} 等价于 getServletContext().getInitParamter("name")
必须掌握cookie隐含对象写法
Cookie[] cookies = request.getCookies();
if(cookies==null){
out.println("cookie不存在!");
}else{
for(Cookie cookie : cookies){
if(cookie.getName().equals("address")){
out.println(cookie.getValue());
}
}
}
使用EL : ${cookie.address.value }
4、EL获取数据值,经常需要对取得数据值进行处理 ----- EL函数
步骤:
第一步:编写java类,提供static方法
第二步:编写tld文件 ,在tld文件中对函数进行定义描述
sun在jstl中提供一套EL函数库,这套函数在导入jstl的jar包后,可以直接使用
1) 导入jstl.jar
2) 在JSP页面内,引入函数库名称空间
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
* 在jstl.jar 存在 META-INF/fn.tld 当中定义EL函数库
3) sun提供EL函数库主要对字符串进行操作 提供16个函数
语法:${fn:toUpperCase('asdasDSFSDF')}
外包项目,jsp内部不允许定义脚本元素 <%%> ----- 必须用标签库和表达式语言 实现<%%> 代码效果
使用jstl步骤
1、去官网上下载jstl的jar 1.0 1.1 1.2
1.1和1.2 基本一样 Servlet2.4(javaee1.4 ) 以后提出的
1.0 在 javaee1.3 之前提出的
* EL 在 javaee1.4 这个版本 纳入规范的 , jstl1.0 时 EL还没有纳入规范,所有1.0标签默认不支持EL
的
2、jar包导入
jstl1.1 两个jar jstl.jar standard.jar ----- jstl.jar 接口API standard.jar 代码实现
将两个jar包 复制工程/WebRoot/WEB-INF/lib 目录中
3、在jsp页面内 通过taglib指令 引入jstl 标签库对应uri
JSTL分为五类:core核心标签 fmt国际化标签 sql数据库标签 xml操作xml标签 fn是EL函数库
因为数据库操作和xml操作,都将代码编写Servlet中 ,所以 sql标签库和xml标签库不学习了
每个标签库在jar/META-INF/ 对应一个tld文件
例如:c.tld 是jstl1.1版本的 c-1_0.tld 是 jstl1.0 版本标签库
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 导入1.1
<%@taglib uri="http://java.sun.com/jstl/core" prefix="c" %> 导入1.0 不支持EL
<%@taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %> 导入1.0 支持EL
* /jstl/demo.jsp(15,0) According to TLD or attribute directive in tag file, attribute test
does not accept any expressions
12个核心标签库标签
1、c:out 用于将内容输出到页面上 ------- 输出EL值、提供默认值、HTML转义输出功能
2、c:set 用于设置一个变量或者属性 ---- 向四个数据范围保存一个数据,对四个数据范围一个已经存在
对象修改其属性值
3、c:remove 用于移除四个数据范围的数据
4、c:catch 相当于try -- catch代码块 ----- 捕获异常,将异常对象保存page指定属性中
5、c:if 取代页面if 条件判断
6、c:choose c:when c:otherwise 实现if -- else if -- else效果 --- 实现 switch 效果
7、c:forEach 实现 foreach循环效果 ----- 遍历数组、List、Map、控制指定循环次数求和、在特殊次数
进行操作
8、c:forTokens 完成字符串切割
9、c:param 不能单独使用,通常与url相关标签一起使用 ,与c:url一起使用完成中文编码
10、c:import 导入目标页面,将目标页面内容保存起来,再进行使用
11、c:url 完成URL重写 (客户端禁用cookie ,URL重写拼接jSessionId),结合param对中文进行url编码
12 c:redirect 标签用于实现请求重定向
常用:c:set c:if c:forEach c:url进行中文url编码 c:redirect
总结:
1、JSP 和Servlet关系
2、JSP运行原理
3、JSP 脚本元素三种 <%! %> <%=%> <% %>
4、JSP三种注释
5、page指令 contentType和pageEncoding区别
6、错误友好页面 web.xml 配置
7、<%@include %> 与 <jsp:include> 原理区别
8、<jsp:forward>转发 <c:redirect>重定向
9、EL 获取数据 . []用法
10、empty not 使用
11、${pageContext.request.contextPath } 取得工程名 /day08 ----- ${cookie.name.value } 快速获得
cookie值
12、EL 使用 JSTL提供EL函数库
13、JSTL 区分1.0 和 1.1
14、常用core标签
c:set 、c:if 、c:forEach 、c:url和c:param编码、 c:redirect