首页 > 代码库 > Java 笔记(8)

Java 笔记(8)

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 传递浏览器采用编码


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属性 
  <u r i > h t t p:  // j a v a . s un . co m / j s p/ j s t l/ c o r e </uri> ----- 就是uri属性 


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获得异常信息 
* 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输出内容之前 


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=http://www.mamicode.com/"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 u r i = " h t t p : / /  j a v  a. s u  n.  c o m / j sp / j s t l / f u n c t i o n s "  p r e f i x = " f n" %>
* 在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 u r i = " h t t p : / /j a  va  .s u n . c o m / j s p /  js t l / c o re  " prefix="c" %>  导入1.1 
<%@taglib u r i = " h t t p : //  ja v a . s u n . c  om /j s t l / c o r e "    pr e f i x ="c" %> 导入1.0  不支持EL 
<%@taglib u r i = " h t t p: / / j a v a. s u n . c o m / j s t l / c o re _ r t "   p r e f i x =  "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: u r l  完成URL重写 (客户端禁用cookie ,URL重写拼接jSessionId),结合param对中文进行u r  l编码 
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:  u r l和c:param编码、 c:redirect