引用袁杰老师上课笔记
1. 回顾
会话技术:
保存数据!
客户端浏览器:
Cookie会话技术
原理:
服务器发送数据(set-cookie, 响应头)给浏览器保存 ,
再次请求是带着数据(cookie,请求头)访问服务器
API:
//1.创建cookie
Cookiecookie = new Cookie(key,value);
//设置有效路径、有效时间
Cookie.setPath(“/web应用上下文”);
Cookie.setMaxAge(秒);// 设置cookie持久化时间
//2.把数据发送给浏览器保存
response.addCookie(cookie);
//再次访问时候,获取cookie信息
Cookie[]cs = request.getCookies();
服务器端:
Session会话技术; session会话技术存储数据,存储原理基于cookie;
API:
//1. 创建session对象
HttpSession session =request.getSession();// (true)先检查是否为同一个会话,如果为同一个会话,直接取出会话对象!
HttpSessionsession = request.getSession(false);// 直接获取session,不创建新的session对象
//设置值
Void session.setAttribute(key,value);
//获取值
ObectgetAttribute(key)
目标:
JSP&EL&EL函数
2. JSP技术概述
2.1 概念
JavaServer Page, java服务器端页面技术!
Jsp中可以写java代码,jsp由服务器运行?
Jsp就是servlet!
Tomcat作为web服务器,运行jsp程序,
Jsp工作目录:E:\Tomcat-6.0.16\work
作用:
开发动态web资源项目的技术!
特点:
向写html代码一样再开发jsp程序!
3. JSP Hello 案例
<body> <h1>我是标题1</h1> <% // jsp中写java代码
// 输出当前时间 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); String now = sdf.format(new Date()); // 向浏览器输出时间 out.print(now);
%> </body> |
4. JSP 运行原理
第一次访问:
Hello.jsp-----à服务器把jsp翻译为hello_jsp.java文件
--à 服务器对翻译的java文件进行,编译,生成: hello_jsp.class字节码文件
-à 运行
第n次访问:
服务器会自动检查jsp页面是否有修改,如有修改再重新翻译、编译!
问题:
Jsp页面如何运行?
1. jsp中有java代码,也有html代码,如何运行?
Html : 通过out对象向浏览器输出内容
Java:直接拷贝到翻译后的java文件中!
2. 为什么说jsp是servlet?
翻译后的*.java文件,自动继承:
class hello_jsp extends org.apache.jasper.runtime.HttpJspBase
public abstract class HttpJspBase
extends HttpServlet
所以,jsp、是servlet!
3. jsp页面为什么可以直接使用out对象?
在翻译后的service(..) 方法中,有声明out对象:
如:JspWriter out;
5. JSP 语法
5.1 Jsp表达式
语法:<%= %>
作用:1. 取值; 2.计算表达式结果
5.2 Jsp代码片段
语法:<% // java代码 %>
作用:
定义定义、声明多行java代码!
(翻译到service方法里面)
5.3 Jsp声明
语法:<%! // 声明全局变量、方法 %>
注意:
Jsp表达式中只有一行代码,不能有分号
<%=num %>
Jsp声明时候注意:
<body> <%=getDate() %>
<%! int num; // 定义一个方法,返回当前时间 public String getDate() { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); String now = sdf.format(new Date()); return now; }
// 错误的方法声明:因为与翻译后自动生成的方法”重名“ public void _jspInit() {
} %>
</body> |
<% %> jsp 代码片段: 写多行java代码
<%= %> jsp表达式: 取值与计算
<%! %> jsp声明: 定义成员变量
5.4 模板元素
Jsp中html代码部分,叫做模板元素!
5.5 Jsp注释
Html注释:<!—注释内容 -->, 客户端可以看到
JSP注释:
语法:<%-- 注释内容 --%>
特点:客户端浏览器看不到,并且不进行翻译
5.5 Jsp处理指令
处理指令:不产生任何可见输出,告诉解析器如何解析执行!
5.5.1 taglib指令
引入自定义标签,或标签库文件
<%@taglibprefix="" uri="" %>
5.5.2 Include指令
实现(静态包含)包含!
如果当前页面希望包含其他页面,可以使用include指令实现页面包含!
例如:
需求:
开发一个页面(jsp,html), 头部页面为公共页面,其他页面引入头部页面!
实现:
<!--使用include指令实现页面包含 -->
<%@includefile="/public/head.jsp" %>
特点:
包含页面与被包含页面,合并为一个文件一起翻译!
先合并,再翻译!
注意:
包含页面与被包含页面不能出现重复的全局架构标签!
5.5.3 Page指令
<%@page
language="java" 指定当前jsp的语言环境
import="java.util.*" 导入包
1.jsp页面默认导入的包:
import="java.util.*"
2.导入多个包:
import="java.util.*,cn.itcast.entity.*"
3.(推荐)或者:
<%@pageimport="cn.itcast.entity.User"%>
pageEncoding="UTF-8" 指定jsp翻译时候所使用的编码;
如果没有指定contentType的编码,他会自动设置
ContentType的编码;
通常设置pageEncoding即可!
contentType="text/html;charset=utf-8" 指定向浏览器输出数据时候使用的编码
autoFlush="true" 自动刷新
buffer="8kb" 缓存大小,默认为8kb
errorPage="" 指定当出现错误的时候,跳转到的目标错误页面!
isErrorPage="false" 指定当前页面为错误页面,一旦设置后,在当前页面就可以使用exception对象
关于项目中异常的全局配置,可以在web.xml中:
注意:当页面中配置errorPage="/error/500.jsp",会覆盖全局的配置! (优先)
<!-- 正式部署环境:配置错误页面,1.根据错误代码配置; 2.根据异常类型配置 --> <error-page> <!-- 错误状态码 --> <error-code>404</error-code> <location>/error/404.jsp</location> </error-page> <error-page> <!-- 异常类型 --> <exception-type>java.lang.NullPointerException</exception-type> <location>/error/null.jsp</location> </error-page> |
extends="" 指定继承的类
isELIgnored="false" 是否忽略el表达式, 默认为false不忽略
isThreadSafe="true" 服务器是否产生多个servlet实例
session="true" jsp页面是否默认创建session对象
%>
5.5.4 Jsp标签(动作)
Ø forward标签,主要用于转发
Ø param标签,转发时候带的参数; 必须要放到forward或include标签体中
Ø include 实现动态包含
使用:
<jsp:includepage="/public/head.jsp"></jsp:include>
特点:
先编译,再合并!
(包含页面与被包含页面各自翻译、编译,再在运行时候合并在一起显示!)
注意:
1. html标签最好不要重复
2. 不能包含重复的page指令属性值,除了编码与导包属性!
Ø 举例:
<jsp:forwardpage="/index.jsp">
<jsp:param value="china" name="cn"/>
</jsp:forward>
<jsp:include page=""></jsp:include>
6. JSP与servlet,JSP开发最佳实践
软件开发中,要求代码:高内聚,低耦合!
(类内部之间的关系越紧密越好,类与类之间的关系越少越好!)
根据这个思想,开发项目时候:
业务逻辑代码,界面展示代码, 分离!
便于美工人员维护系统!
Servlet:
开发动态web网站的技术!
只要与servlet接口有关的java程序,并且由服务器与运行,就叫servlet!
Servlet:可以输出html代码,可以写java代码!
Servlet:
只处理业务逻辑! 不涉及界面显示!
Jsp:
开发动态web网站的技术!
Jsp中可以写html代码,也可以写java代码!
JSP:
只显示数据! 不涉及任何业务逻辑处理!
最终,要求jsp中不要出现java代码!
上午:
Jsp指令:
Page 指令, 设置引入的包、页面翻译时候编码、缓存大小、是否打开session….
Include静态包含
Taglib指令, 引入标签库文件
动态包含与静态包含:
动态包含: 翻译的结果有多个,运行时期合并一起显示
先编译,再合并
静态包含:翻译为一个java文件!
先合并,再翻译!
Jsp语法:
<%=%> 取值,jsp表达式
<%%> 代码片段
<%!%> jsp声明
<%----%> jsp注释
7. 九大内置对象
内置对象:服务器自动创建,程序员只需要知道其用法并在适当的时候使用!
request HttpServletRequest 封装请求信息
session HttpSession 当前会话
application ServletContext sevlet上下文对象,代表当前web应用
response HttpServletResponse 设置响应信息
config ServletConfig servlet配置信息
exception Throwable 异常对象
page this 当前实例
out JspWriter 带缓冲功能的PrinterWriter对象,用于向浏览器输出页面内容
pageContext PageContext 1. 代表jsp运行时环境; 2.域对象; 3. 其他方法
7.1 out对象
l JspWriter out; //out 对象的类型
out = pageContext.getOut();
out隐式对象用于向客户端发送文本数据。
l out对象是通过调用pageContext对象的getOut方法返回的,其作用和用法与ServletResponse.getWriter方法返回的PrintWriter对象非常相似。
l JSP页面中的out隐式对象的类型为JspWriter,JspWriter相当于一种带缓存功能的PrintWriter,设置JSP页面的page指令的buffer属性可以调整它的缓存大小,甚至关闭它的缓存。
l 只有向out对象中写入了内容,且满足如下任何一个条件时,out对象才去调用ServletResponse.getWriter方法,并通过该方法返回的PrintWriter对象将out对象的缓冲区中的内容真正写入到Servlet引擎提供的缓冲区中:
ü 设置page指令的buffer属性关闭了out对象的缓存功能
ü out对象的缓冲区已满
ü 整个JSP页面结束
带缓冲功能的PrinterWriter对象,用于向浏览器输出页面内容!
Jsp输出数据--à写入JspWriter的缓冲区中--à再把缓冲区内容写入到PrintWriter对象中,最后通过PrintWriter对象向浏览器输出数据!
什么情况缓冲区的数据输出到浏览器?
1. 关闭缓冲
2. 或缓冲满了
3. jsp页面执行结束
此时,out对象中缓冲区数据才通过printerWriter对象输出到浏览器中!
7.2 pageContext对象
1. pageContext代表了当前jsp的运行时环境,通过次对象可以获取其他8大隐士对象的引用!
2. 域对象: 保存数据、获取数据、数据范围
7.2.1 获取其他八大隐士对象
<body> <% System.out.println(pageContext.getRequest() == request); System.out.println(pageContext.getOut() == out); System.out.println(pageContext.getResponse() == response); System.out.println(pageContext.getPage() == page); System.out.println(pageContext.getSession() == session); System.out.println(pageContext.getServletContext() == application); System.out.println(pageContext.getServletConfig() == config);
%> </body> |
自定义标签时候,会频繁使用到pageContext对象!
业务处理方法:
public void deal(PageContext page){
}
7.2.2 (重点)域对象
域:1. 容器; 2. 范围
pageContext是一个域对象,作用范围最小的域对象,保存在pagecontext对象中的数据只在当前页面有效!
常用方法: 保存、获取数据
<body> <% // 往pageContext域中存储数据,只能在当前页面获取次数据 pageContext.setAttribute("usa","America"); %>
<!-- 获取page域 --> <%=pageContext.getAttribute("usa")%> </body> |
7.2.3 通过pageContext对象,往其他域中存储数据
<body> <% // 通过pageContext对象,往request域中存储数据 pageContext.setAttribute("usa","America",PageContext.REQUEST_SCOPE); %>
<!-- 通过pageContext对象,获取其他域中数据 --> <%=pageContext.getAttribute("usa",PageContext.REQUEST_SCOPE)%> </body> |
7.2.4 (重点)通过pageContext对象,自动搜索各个域的值
自动搜索各个域中值: 按域的范围从小到大搜索,找到后立刻返回: page域、request域、session域、application域
<body> <!-- 数据准备(模拟) --> <% //分别往page域、request、session、application域中存储数据 pageContext.setAttribute("request","page域");
request.setAttribute("session","request"); session.setAttribute("application","session"); application.setAttribute("application","application");
%>
<!-- 数据获取 --> <!-- 获取request域中数据 --> <%=pageContext.getAttribute("request",PageContext.REQUEST_SCOPE)%> <!-- 自动搜索各个域中值:按域的范围从小到大搜索,找到后立刻返回: page域、request域、session域、application域 --> <%=pageContext.findAttribute("session")%> </body> |
7.2.5 (了解)pageContext对象其他方法
<body> <% //转发、页面包含 //1. 通过request对象 request.getRequestDispatcher("").forward(request,response); //2. 通过servletContext对象实现转发 application.getRequestDispatcher("").forward(request,response); //3. 通过pageContext实现转发 pageContext.forward("/跳转资源"); //4. 使用jsp动作实现转发(推荐)
//包含 pageContext.include("");//动态包含 %> </body> |
8. 四大域对象
域对象:
1. 服务器创建
2. 保存数据
3. 数据有范围
讲一下四大域对象,及区别?
pageContext 存储的数据在当前页面有效 每次访问页面创建
Request 存储的数据只在转发后有效 每次请求服务器创建
Session 存储的数据在会话内有效 打开浏览器访问资源..创建
servletContext 存储的数据在当前web应用有效(服务器启动,在停止之前都可以访问次域中数据) 服务器启动时候创建此对象
9. EL表达式语言
使用域对象: 可以保存数据!
保存数据目的是为了显示数据,在jsp页面显示数据!
如果在jsp页面中获取域中数据,要使用<%= %> 获取数据。jsp页面最好不要出现一行java代码, 所以要学习新的表达式取值语言,叫el表达式语言!
语法:${}
9.1 El表达式语言:
1. 取值; 取域中的值
2. 运算; 计算表达式的值
从域中取值:
<% // 模拟保存数据 pageContext.setAttribute("page1","page1"); request.setAttribute("session","China"); session.setAttribute("session","session"); application.setAttribute("app","application1"); %>
<!-- 1. 取域中的值: 相当于,pageContext.findAttribute(key) 依次搜索page/request/session/application域中数据,找到后立刻返回; 2. (推荐)指定域,取值 el表达式语言提供的表示域范围的内置对象 pageScope requestScope sessionScope applicationScope
对比: ${app}和 ${applicationScope.app} 指定域取值的好处:1.效率高; 2. 程序可读性强,便于错误排查
--> ${app} 和 ${applicationScope.app}<hr/> ${requestScope.session }<!-- 指定从request域中取数据 --> ${sessionScope.session }<!-- 指定从session域中取数据 -->
${adadas }<!-- 如果从域中获取不到数据,返回"",而不是null --> |
El表达式语言提供的内置对象
pageScope 指定从page域中取值
requestScope 指定从request域中取值
sessionScope 指定从session域中取值
applicationScope 指定从servletContext域中取值
pageContext el表达式语言提供了pageContext内置对象
使用:
${sessionScope.cn} 指定从session域中取值
${cn} 依次查找page/request/session/application域;
通过pageContext内置对象,获取上下文路径:
<ahref="${pageContext.request.contextPath }/jsps/index.jsp">点我连接3</a>
案例:
<body> <% // 模拟保存数据 pageContext.setAttribute("page1","page1"); request.setAttribute("session","China"); session.setAttribute("session","session"); application.setAttribute("app","application1"); %>
<!-- 取值 --> <ahref="/day12/jsps/index.jsp">点我连接</a> <ahref="<%=((HttpServletRequest)request).getContextPath()%>/jsps/index.jsp">点我连接</a> <ahref="${pageContext.request.contextPath }/jsps/index.jsp">点我连接3</a>
<!-- 输出当前来访者ip --> ${pageContext.request.remoteAddr } </body> |
El表达式语言,取值
取出域中值:
获取对象的值
${user.id}
获取复杂对象的值
${user.address.province}
获取list集合中值
${list[0].id}
获取map中数据
${map.cn}
<body> <% // 1.模拟保存数据 pageContext.setAttribute("page1","page1");
// 2. 保存user对象到域中 User user = new User(); user.setId("U-000001"); Address add = new Address(); add.setProvince("广东省"); // 保存到user对象中 user.setAdrress(add); pageContext.setAttribute("users",user);
// 3. 保存list集合数据 User user2 = new User(); user2.setId("U-000001"); User user3 = new User(); user3.setId("U-000002"); // 创建list集合 List list = new ArrayList(); list.add(user2); list.add(user3); // 保存 pageContext.setAttribute("list",list);
//4. 保存map数据 Map map = new HashMap(); map.put("c-n","China"); map.put("usa","America"); //保存 pageContext.setAttribute("map",map);
%>
${pageScope.page1 } <!-- 获取user对象的id --> ${pageScope.users.id } <!-- 获取users用户的省份信息 --> ${pageScope.users.adrress.province } <hr/> <!-- 获取list集合中数据 --> ${pageScope.list[1].id }
<!-- 获取map中数据 --> ${pageScope.map['c-n'] } </body> |
重点:
1. el表达式
2. 9大内置对象与四大域对象
3. pageContext对象
4. jsp语法: 基本语法<%%>, jsp标签
5. 熟悉jsp原理