三、会话技术
-
会话:
用户打开浏览器,访问web服务器的资源,会话建立,直到有一方断开连接,会话结束。在一次会话中可以包含多次请求和响应。
-
会话跟踪:
一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次会话的多次请求间共享数据。
3.1 cookie对象
-
cookie概念
客户端会话技术,将数据保存到客户端,以后每次请求都携带Cookie数据进行访问。
-
cookie介绍
Cookie是浏览器提供的一种技术,通过服务器的程序能将一些只须保存在客户端,或者在客户端进行
处理的数据,放在本地的计算机上,不需要通过网络传输,因而提高网页处理的效率,并且能够减少服
务器的负载,但是由于 Cookie 是服务器端保存在客户端的信息, 所以其安全性也是很差的。例如常见
的记住密码则可以通过 Cookie 来实现。
-
cookie格式
键值对用“=”链接,多个键值对间通过“;”隔开
3.1.1 cookie对象的创建与发送
通过 new Cookie("key","value");
来创建一个 Cookie 对象
通过response对象的addCookie(cookie);
方法来发送一个cookie对象
// 创建Cookie对象
Cookie cookie = new Cookie("uname","zhangsan");
// 发送Cookie对象
response.addCookie(cookie);
3.1.2 Cookie的获取与遍历
通过request对象的getCookies()
方法来获取cookie
通过遍历获取单个cookie,getName()获取 Cookie 的名称,getValue()获取 Cookie 的值
//获取所有cookie,得到的是一个数组
Cookie[] cookies = request.getCookies();
//获取单个cookie
if(cookies !=null && cookies.length > 0){
for(Cookie cookie:cookies){
// 遍历Cookie数组
for (Cookie cookie : cookies){
System.out.println(cookie.getName()); System.out.println(cookie.getValue());
}
}
3.1.3 设置cookie到期时间
用cookie.setMaxAge();
方法来实现cookie的到期时间
- 负整数
- 若为负数,表示不存储该 cookie。
- cookie 的 maxAge 属性的默认值就是-1,表示只在浏览器内存中存活,一旦关闭浏览器窗口,那么 cookie 就会消失。
- 正整数
- 存储指定秒数
- 0
- 表示删除当前cookie
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//创建cookie对象
Cookie cookie1 = new Cookie("name","卢本伟牛逼");
Cookie cookie2 = new Cookie("age","20");
Cookie cookie3 = new Cookie("job","programmer");
//设置到期时间 负数
cookie1.setMaxAge(-2);
//设置到期时间 0
cookie2.setMaxAge(0);
//设置到期时间 正整数
cookie3.setMaxAge(3 * 24 * 60 * 60);
//响应cookie
response.addCookie(cookie1);
response.addCookie(cookie2);
response.addCookie(cookie3);
Cookie cookie = new Cookie("uname", null);
cookie.setMaxAge(0);
response.addCookie(cookie);
}
JsessionId 唯一的会话标识
- 当浏览器访问后台时,默认携带jsessionID,只有前台后台的JsessionID存在并且一致时才能接着会话
3.2 session 对象
-
session概念
服务端会话跟踪技术:将数据保存到服务端。
Session是存储在服务端而Cookie是存储在客户端
3.2.1 Session的基本使用
在JavaEE中提供了HttpSession接口,来实现一次会话的多次请求之间数据共享功能。
使用步骤:
- 通过request对象的
getSession()
方法来创建session对象
HttpSession session = request.getSession();
-
Session对象提供的功能:
-
存储数据到 session 域中
void setAttribute(String name, Object o) //给session对象设置域属性uname并赋值zhangsan session.setAttribute("uname","zhangsan");
-
根据 key,获取值
Object getAttribute(String name) //通过前面设置的域属性uname来获取属性值zhangsan(通过k获取v) session.getAttribute("uname");
-
根据 key,删除该键值对
void removeAttribute(String name) //通过前面设置的域属性uname来删除属性值zhangsan(通过k获取v) session.removeAttribute("uname");
-
3.2.2 session手动设置失效时间
-
设置tomcat/conf/web.xml 中的session-config 单位是分钟 统一设置所有的session失效时间
-
设置当前会话存活的时间
- session.setMaxInactiveInterval(); //单位是秒
-
设置当前会话立即失效,销毁session对象
- session.invalidate();
-
关闭浏览器或者服务器关闭会话也会失效
public class Servlet08 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 如果session对象存在,则获取;如果session对象不存在,则创建
HttpSession session = request.getSession();
//设置session的失效时间
session.invalidate();
System.out.println(session.getId());
}
}
四、JSP
4.1 JSP介绍
-
JSP称为Java的动态服务器端网页技术,(Java Server Page).
jsp是一个特殊的页面,既可以写java代码,也可以写HTML代码,本质上是一个servlet
-
Java程序直接嵌入到了HTML中,页面称为jsp页面(脚本语言)
-
Java嵌入HTML方式
- <% java代码 %> :在service方法中写代码(局部位置)
- <%! java代码 %>:在成员位置写代码(成员位置)
- <%= java代码 %> :向页面中输出数据(IO流技术) System.out.println(“在控制台输出”)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<!--
< % java代码 %> :在方法中写代码(局部位置)
-->
<%
//局部变量
int a = 10;
String s = "abc";
System.out.println(a);
System.out.println(s);
%>
<!--
< %! java代码 %>:在成员位置写代码(成员位置)
-->
<%!
/*
成员变量
*/
double d = 8.8;
%>
<!--
< %= java代码 %> :向页面中输出数据(IO流技术)
-->
<%=a%>
<%=s%>
<%=d%>
</body>
</html>
4.2 jsp的九大内置对象
内置对象:就是jsp页面中已经创建好的对象,我们可以直接使用
-
pageContext 最小域对象,作用范围是当前页面(打开jsp页面有对象,关闭页面对象就消失)
-
request对象:一次请求访问的多个资源(请求转发)
-
response对象:一次会话的多个请求
-
ServletContext对象,在JSP写对象,只能写 application
-
ServletConfig对象,在JSP写对象,只能写config
-
HttpSession session:域对象存储数据,作用域一次会话,只要浏览器不关闭,数据就一直有效(默认值30分钟)
-
JspWriter out:字符输出流 ,可以在jsp页面中输出数据
-
Object page:当前对象,就是当前的Servlet,就是this
-
exception异常:在页面中输出异常信息
4.3 jsp指令
- 分类:
- page:配置jsp页面
- include
- taglib:导入资源
4.4 EL表达式
EL(Expression Language) 是为了使 JSP 写起来更加简单。表达式语言的灵感来自于 ECMAScript和 XPath 表达式语言,它提供了在 JSP 中简化表达式的方法,让 Jsp 的代码更加简化。
-
特点:
- EL表达式语言,直接出现JSP页面中
- EL表达式可以减少jsp中java代码(<% %>)的书写
-
**作用: **
- 从域对象取出数据
-
语法
- ${el表达式的代码}
EL 表达式一般操作的都是域对象中的数据,操作不了局部变量。
- 域对象的概念
在 JSP 中一共有四个:pageContext, request, session, application;范围依次是,本页面,一次请求, 一次会话,整个应用程序。
当需要指定从某个特定的域对象中查找数据时可以使用四个域对象对应的空间对象,分别是: pageScope, requestScope, sessionScope, applicationScope。
而 EL 默认的查找方式为从小到大查找,找到即可。当域对象全找完了还未找到则返回空字符串""。
4.5 EL表达式的使用
4.5.1.获取域对象的数据
- 设置域对象中的数据
- 用EL表达式获取域对象的值
<%
pageContext.setAttribute("uname","zhangsan"); // page作用域
request.setAttribute("uname","lisi"); // request作用域
session.setAttribute("uname","wangwu"); // session作用域
application.setAttribute("uname","zaholiu"); // application
%>
<%-- 获取域对象中的数据:默认查找方式为从小到大,找到即止。若四个范围都未找到,则返回空字符串。- -%>
${uname} <!-- 输出结果为:zhangsan -->
<h2>${requestScope.uname}</h2>
<h2>${sessionScope.uname}</h2>
<h2>${applicationScope.uname}</h2>
4.5.2.获取Javabean对象的值
- 设置域对象中的数据
- 用EL表达式获取域对象的值
${域名城.键名.属性名}
<%
User user = new User();
user.setUserId(1);
user.setUname("zhangsan");
user.setUpwd("123456");
request.setAttribute("user",user);
%>
<%-- JavBean中的属性字段需要提供get方法 --%>
${user} <%-- 获取对象中的所有属性和值 --%>
${user.uname} <%--获取对象中的uname的属性值zhangsan--%>
${user.upwd}
4.5.3.获取list
- 设置域对象中的数据
- 用EL表达式获取域对象的值
${list[下标] }
<%
List<String> list = new ArrayList<String>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
request.setAttribute("list", list);
%>
<%--
获取List中指定下标的数据
${list[下标] } 获取集合的长度
${list.size()}
注:list代表的是存在域对象中的变量名(限域变量名) --%>
${list[1]}
4.5.4.获取Map
-
设置域对象中的数据
-
用EL表达式获取域对象的值
${map["key"] }
或${map.key }
<%
Map map = new HashMap();
map.put("aaa", "111");
map.put("bbb", 2222);
map.put("ccc-a", 333);
request.setAttribute("map", map);
%>
<%--
获取Map中指定值
${map["key"] } 或 ${map.key }
注: map代表的是存在域对象中的变量名(限域变量名)
--%>
${map.bbb}
${map["bbb"]}
4.5.5.empty
- 概念:
- 判断域对象是否为空。为空,返回true;不为空返回false;
- 语法:
${empty 限域变量名 }
${!empty 限域变量名 }
或${not empty 限域变量名 }
${empty user.uname}
${empty a}
- 注意page标签的i
sELIgnored
属性值要为false
才能使用EL表达式
<%@ page contentType="text/html;charset=UTF-8" isELIgnored="false" language="java" %>
4.6 JSTL
JSTL用于简化和替换jsp页面上的java代码
4.6.1 JSTL的使用步骤
-
添加坐标依赖
<dependency> <groupId>javax.servlet.jsp.jstl</groupId> <artifactId>jstl-api</artifactId> <version>1.2</version> </dependency>
-
在页面中引入taglib的标签库
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
4.6.2 常用标签
1.if 标签
-
格式:
<c:if test="条件"> 执行语句 </c:if>
-
属性:
- test: 必须有的属性,返回一个Boolean值
- var 接收表达式的结果
- scope 设置当前EL取值的范围
示例:
<%
List list = new ArrayList();
list.add("aaa");
request.setAttribute("list",list);
request.setAttribute("number",3);
%>
<c:if test="${not empty list}">
list不为空,执行这段话
</c:if >
<c:if test ="${number % 2 !=0 }">
${number}为奇数
</c:if>
2.choose标签
choose-when-otherwise
-
格式
<c:choose> <c:when test="<boolean>">...</c:when> <c:when test="<boolean>">...</c:when> ... <c:otherwise>...</c:otherwise> </c:choose>
-
属性
-
choose标签没有属性。
-
when标签只有一个test属性。
-
otherwise标签没有属性。
-
示例:
<%
request.setAttribute("number",3);
%>
<h3>choose标签</h3>
<c:choose>
<c:when test="${number == 1}">星期一</c:when>
<c:when test="${number == 2}">星期二</c:when>
<c:when test="${number == 3}">星期三</c:when>
<c:when test="${number == 4}">星期四</c:when>
<c:when test="${number == 5}">星期五</c:when>
<c:when test="${number == 6}">星期六</c:when>
<c:when test="${number == 7}">星期日</c:when>
<c:otherwise>输入有误</c:otherwise>
</c:choose>
3.forEach标签
-
格式
<c:forEach items="<object>" begin="<int>" end="<int>" step="<int>" var="<string>" varStatus="<string>"> </c:forEach>
-
属性
- begin 开始值
- end 结束值
- var 临时变量
- step 步长
- varStatus 循环状态对象
-
forEach varStatus 属性
-
index: 当前这次迭代从 0 开始的迭代索引
-
count: 当前这次迭代从 1 开始的迭代计数
-
first: 用来表明当前这轮迭代是否为第一次迭代的标志
-
last: 用来表明当前这轮迭代是否为最后一次迭代的标志
-
-
普通for循环操作的作用
<c:forEach begin=开始数 end=结束数值 var=限域变量 step=迭代数目></c:forEach> 相当于java的for循环: for(int i = 0; i<结束数值; i++){ } for(int i = 0; i < 10; i++) { }
-
遍历容器作用(迭代器)
<c:forEach items="被循环的集合" var="限域变量名" varStatus="当前成员对象的相关信息"></c:forEach> 相当于java的foreach循环: for(数据类型 变量名:被循环的集合){ } for(String str : list) { }
示例:
//普通for循环操作的作用
<c:forEach begin="1" end="10" var="i" step="2" varStatus="s">
${i} ${s.index} ${s.count}<br>
</c:forEach>
//遍历容器作用(迭代器)
<%
List list = new ArrayList();
list.add("aaa");
list.add("bbb");
list.add("ccc");
request.setAttribute("list", list);
%>
<hr>
<c:forEach items="${list}" var = "str" varStatus="s">
${s.index}${s.count}${str}<br>
</c:forEach>