文章目录
javaWeb
一、课程目标
【掌握】session的使用
【掌握】EL表达式的书写
【理解】jstl的使用
二、session会话
2.1 概念
由客户端第一次向服务器发送请求开始,至多个请求的结束中间的过程称之为会话,javaweb的会话对象,用于保存当前会话过程中需要保存的数据,在下次请求或响应中都可以获取会话中的数据
2.2 工作原理
1)浏览器发出请求到服务器。
2)服务器会根据需求生成Session对象,并且给这个Session对象一个编号,一个编号对应一个Session对象
3)服务器把需要记录的数据封装到这个Session对象里,然后把这个Session对象保存下来。
4)服务器把这个Session对象的编号放到一个Cookie里,随着响应发送给浏览器
5)浏览器接收到这个cookie就会保存下来
6)当下一次浏览器再次请求该服务器服务,就会发送该Cookie
7)服务器得到这个Cookie,取出它的内容,它的内容就是一个Session的编号!!!
8)凭借这个Session编号找到对应的Session对象,然后利用该Session对象把保存的数据取出来!
2.3 使用
2.3.1 添加session
指的是向session中存储数据,因为session的创建是由服务器自动创建的,直接通方法可以获取到当前请求用户的session对象并进行数据的添加
//请求对象提供了直接获取session对象的方法
HttpSession session = request.getSession();
//将数据以key-value的形式存储在session作用域中
session.setAttribute("session", "session数据");
//session存储数据可以看作是map集合
2.3.2 查询session
通过session提供的方法通过指定的name获取value
//请求对象提供了直接获取session对象的方法
HttpSession session = request.getSession();
//session提供了直接获取指定数据与全部数据的方法
//可以直接通过指定key获取session中value的值
System.out.println(session.getAttribute("session"));
//也可以先获取所有的key之后遍历获取数据(不经常使用)
HashMap<String, Object> map=new HashMap<>();
//通过方法获取全部的name数组
String[] valueNames = session.getValueNames();
for (String string : valueNames) {
map.put(string, session.getAttribute(string));
}
System.out.println(map);
2.3.3 修改session
session中存储数据的结构类似于map,所以key不允许重复,所以对session的修改就是重新设置相同key的session数据
//请求对象提供了直接获取session对象的方法
HttpSession session = request.getSession();
//将数据以key-value的形式存储在session作用域中
session.setAttribute("session", "修改后的session数据");
session.setAttribute("session1", "修改后的session数据1");
//session存储数据可以看作是map集合
2.3.4 删除session
HttpSession session = request.getSession();
//删除session是使客户端请求时无法获取指定session中的指定数据
//1、通过修改将指定数据设置为null
session.setAttribute("session", null);
//2、通过session提供的方法将指定数据映射删除
session.removeAttribute("session");
//3、清除对应session的缓存
Cookie cookie=new Cookie("JSESSIONID", "");
cookie.setMaxAge(0);
response.addCookie(cookie);
//4、通过session提供的方法将session对象进行删除
session.invalidate();
2.4 session的生命周期
Session保存在服务器端。为了获得更高的存取速度,服务器一般把Session放在内存里。每个用户都会有一个独立的Session。如果Session内容过于复杂,当大量客户访问服务器时可能会导致内存溢出。因此,Session里的信息应该尽量精简。
Session在用户第一次访问服务器的时候自动创建。需要注意只有访问JSP、Servlet等程序时才会创建Session,只访问HTML、IMAGE等静态资源并不会创建Session。如果尚未生成Session,也可以使用request.getSession(true)强制生成Session。
Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。用户每访问服务器一次,无论是否读写Session,服务器都认为该用户的Session“活跃(active)”了一次。
session的活跃时间是由tomcat进行决定配置的,可以通过相应的配置文件进行修改
<session-config>
<session-timeout>30</session-timeout>
</session-config>
也可以通过相应的方法设置session的活跃时间
session.setMaxInactiveInterval(30);
2.5 session与cookie的区别
从存储方式上比较
Cookie只能存储字符串,如果要存储非ASCII字符串还要对其编码; Session可以存储任何类型的数据,可以把Session看成是一个容器
cookie数据存放在客户的浏览器上,session数据放在服务器上;
单个cookie在客户端的限制是4K,就是说一个站点在客户端存放的COOKIE不能超过4K(不同浏览器不同);
从隐私安全上比较
Cookie存储在浏览器中,对客户端是可见的。信息容易泄露出去。如果使用Cookie,最好将Cookie加密
Session存储在服务器上,对客户端是透明的。不存在敏感信息泄露问题。
从有效期上比较
Cookie保存在硬盘中,只需要设置maxAge属性为比较大的正整数,即使关闭浏览器,Cookie还是存在的
Session的保存在服务器中,设置maxInactiveInterval属性值来确定Session的有效期。并且Session依赖于名为JSESSIONID的Cookie,该Cookie默认的maxAge属性为-1。如果关闭了浏览器,该Session虽然没有从服务器中消亡,但也就失效了。
从对服务器的负担比较
Session是保存在服务器的,每个用户都会产生一个Session,如果是并发访问的用户非常多,是不能使用Session的,Session会消耗大量的内存。
Cookie是保存在客户端的。不占用服务器的资源。像baidu这样的大型网站,一般都是使用Cookie来进行会话跟踪。
三、EL表达式
Expression Language(表达式语言)
3.1 概念
书写在jsp中通过特定的语法对作用域中的数据进行快速获取,减少在jsp页面中java代码的书写,简化开发
3.2 语法
3.2.1 获取传递数据并进行自动转换
获取指定作用域数据并进行自动类型转换(因为保存的是object类型,el表达式在取出后会自动转换为放置之前的类型)
${作用域.name}
属性范围 | EL中的名称 |
---|---|
page | pageScope,例如${pageScope.username},表示在page范围内查找username变量,找不到返回空字符串 |
request | requstScope |
session | sessionScope |
application | applicationScope |
虽然可以通过各个作用域获取相同名字的数据,但是一般我们不会书写相同属性的数据,所以可以直接通过${name}进行获取,但是如果出现相同name可能会导致数据获取出现问题(如果没有书写作用域,那么会从小到大依次进行获取)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
pageContext.setAttribute("test", "page");
request.setAttribute("test", "request");
session.setAttribute("test", "session");
application.setAttribute("test", "application");
%>
page:${pageScope.test}<br>
request:${requestScope.test}<br>
session:${sessionScope.test}<br>
application:${applicationScope.test}<br>
啥都不写:${test }
</body>
</html>
3.2.2 获取指定数据的属性
使用属性获取时是自动根据属性调用对应的get方法进行获取
对象.属性
对象[“属性”]
<%@page import="com.yunhe.el.Student"%>
<%@page import="com.yunhe.el.Teacher"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
Teacher t=new Teacher("tname","tage");
Student s=new Student("sname",18,t );
session.setAttribute("stu", s); %>
<!-- 获取并进行自动类型转换 -->
${s}
<!-- 获取指定对象后获取对应的属性 -->
=${stu.teacher.name}
<hr>
${stu["teacher"]["name"]}
</body>
</html>
3.2.3 获取集合中的数据
List集合
<%@page import="java.util.ArrayList"%>
<%@page import="com.yunhe.el.Student"%>
<%@page import="com.yunhe.el.Teacher"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
ArrayList<Teacher> list=new ArrayList<>();
list.add(new Teacher("t1","t1"));
list.add(new Teacher("t2","t2"));
list.add(new Teacher("t3","t3"));
request.setAttribute("teacherlist", list);
%>
<!-- 获取 集合中的数据 -->
<!-- 通过类似于数组的获取方式进行获取 -->
${teacherlist[1]}
<hr>
${teacherlist.get(1)}
</body>
</html>
map集合
<%@page import="java.util.HashMap"%>
<%@page import="java.util.ArrayList"%>
<%@page import="com.yunhe.el.Student"%>
<%@page import="com.yunhe.el.Teacher"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
HashMap<String,String> names = new HashMap<>();
names.put("one","LiYang");
names.put("two","WangHua");
request.setAttribute("names",names);
%>
<!-- 可以将map集合的key当做对象的属性进行获取 -->
姓名:${names.one}<br/>
姓名:${names["two"] }<br/>
姓名:${names.get("one") }<br/>
</body>
</html>
3.2.4 El操作符
与java中的操作符使用方法一致,并提供了仅用于el的对应操作符的语法
关系操作符 | 说明 | 示例 | 结果 |
---|---|---|---|
==(或eq) | 等于 | 23 = = 5 或 {23==5}或 23==5或{23 eq 5} " a " = = " a " 或 {"a" =="a"}或 "a"=="a"或{“a” eq “a”} | falsetrue |
!=(或ne) | 不等于 | 23 ! = 5 或 {23!=5}或 23!=5或{23 ne 5} | true |
<(或lt) | 小于 | 23 < 5 或 {23<5}或 23<5或{23 lt 5} | false |
>(或gt) | 大于 | 23 > 5 或 {23>5}或 23>5或{23 gt 5} | true |
<=(或le) | 小于等于 | 23 < = 5 或 {23<=5}或 23<=5或{23 le 5} | false |
>=(或ge) | 大于等于 | 23 > = 5 或 {23>=5}或 23>=5或{23 ge 5} | ture |
逻辑操作符 | 说明 | 示例 | 结果 |
---|---|---|---|
&&(或and) | 逻辑与 | 如果A为true,B为false,则A&&B(或A and B) | false |
||(或or) | 逻辑或 | 如果A为true,B为false,则A||B(或A or B) | true |
! (或not) | 逻辑非 | 如果A为true,则!A (或not A) | false |
变量 a不存在,则${empty a}返回的结果为true
n
o
t
e
m
p
t
y
a
或
{not empty a}或
notemptya或{!empty a}返回的结果为false
3.3 el隐式对象
el表达式可以对当前服务存储在指定隐式对象中的数据进行获取
对象名称 | 说 明 |
---|---|
pageScope | 返回页面范围的变量名,这些名称已映射至相应的值 |
requestScope | 返回请求范围的变量名,这些名称已映射至相应的值 |
sessionScope | 返回会话范围的变量名,这些名称已映射至相应的值 |
applicationScope | 返回应用范围内的变量,并将变量名映射至相应的值 |
param | 返回客户端的请求参数的字符串值 |
paramValues | 返回映射至客户端的请求参数的一组值 |
pageContext | 提供对用户请求和页面信息的访问 |
四、JSTL
4.1 概念
jstl(JavaServerPages Standard Tag Library) JSP标准标签库
jsp标准标签库,用于配合指令与el表达式完成jsp页面上所有动态操作,使页面java代码的书写降到最低
4.2 使用
1、导入相应的jar包 jstl.jar standard.jar
2、在使用jstl的jsp页面中添加标签的引入(类似于java的导包)
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
3、使用相应标签完成相应功能
4.2.1 通用标签
User.java
package com.yunhe.pojo;
import java.io.Serializable;
import java.util.Objects;
public class User implements Serializable {
private String username;
private String password;
private String roleName;
public User() {
}
public User(String username, String password, String roleName) {
this.username = username;
this.password = password;
this.roleName = roleName;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
", roleName='" + roleName + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(getUsername(), user.getUsername()) && Objects.equals(getPassword(), user.getPassword()) && Objects.equals(getRoleName(), user.getRoleName());
}
@Override
public int hashCode() {
return Objects.hash(getUsername(), getPassword(), getRoleName());
}
}
set标签
<%@ page import="com.yunhe.pojo.User" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<%-- c是前缀 在taglib设置时设置的前缀是什么 使用时前缀就是什么 --%>
<%-- 1、将数据存储至指定作用域 --%>
<c:set var="name" value="值" scope="session"/>
<%-- var 存储到作用域的名字 value存储到作用域的值 scope存储的作用域--%>
${name}
<%--2、为指定对象赋值 --%>
<% User u=new User();
session.setAttribute("user",u);
%>
<c:set target="${user}" property="username" value="admin"/>
<c:set target="${user}" property="password" value="123456"/>
<c:set target="${user}" property="roleName" value="管理员"/>
<%-- target设置属性的对象(一般使用el表达式获取) property设置的属性 value设置的值 --%>
${user}
</body>
</html>
out标签
用于获取输出指定数据
<%@ page import="com.yunhe.pojo.User" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<% User u=new User();
u.setPassword("123456");
session.setAttribute("user",u);
%>
<%-- out标签 将结果输出到控制台 类似于el表达式输出 out.print() --%>
<%-- el表达式值为空时没有输出 out标签至为空时可以设置默认值 --%>
<c:out value="${user.username}" default="用户名未设置"/>
<c:out value="${user.password}" default="密码未设置"/>
<c:out value="${user.roleName}" default="角色未设置"/>
</body>
</html>
remove标签
用于删除指定作用域数据
<%@ page import="com.yunhe.pojo.User" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<% User u=new User();
u.setPassword("123456");
session.setAttribute("user",u);
%>
<%-- remove标签 移除指定作用域指定数据 --%>
<c:remove var="user" scope="session"/>
<%-- out标签 将结果输出到控制台 类似于el表达式输出 out.println() --%>
<%-- el表达式值为空时没有输出 out标签至为空时可以设置默认值 --%>
<c:out value="${user.username}" default="用户名未设置"/>
<c:out value="${user.password}" default="密码未设置"/>
<c:out value="${user.roleName}" default="角色未设置"/>
</body>
</html>
4.2.2 条件标签
if标签
<%@ page import="com.yunhe.pojo.User" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<% User u = new User();
u.setUsername("admin");
u.setPassword("123456");
u.setRoleName("0");//0学生 1老师 2管理员
session.setAttribute("user", u);
%>
<%-- c:if标签 对结果进行判断如果为true则在页面输出标签内容 --%>
<c:if test="${true}" var="names" scope="page"></c:if>
<%-- test使用el表达式获取数据后进行判断 var用于声明变量保存判断的结果 scope用于设置变量存储的作用域 --%>
<table>
<thead>
<tr>
<th>账号</th>
<th>密码</th>
<th>角色</th>
</tr>
</thead>
<tbody>
<tr>
<td>
${user.username}
</td>
<td>
${user.password}
</td>
<td>
<c:if test="${user.roleName eq '0'}" var="c1" scope="page">
学生
</c:if>
<c:if test="${user.roleName eq '1'}" var="c2" scope="page">
老师
</c:if>
<c:if test="${user.roleName eq '2'}" var="c3" scope="page">
管理员
</c:if>
</td>
判断结果1${c1}
判断结果2${c2}
判断结果3${c3}
</tr>
</tbody>
</table>
</body>
</html>
choose标签
<%@ page import="com.yunhe.pojo.User" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<% User u = new User();
u.setUsername("admin");
u.setPassword("123456");
u.setRoleName("5");//0学生 1老师 2管理员
session.setAttribute("user", u);
%>
<%-- c:choose标签 用于完成if。。else的书写 只有在每个分支上拥有test属性用于判断数据的结果 --%>
<c:choose>
<c:when test="${user.roleName eq '0'}">
学生
</c:when>
<c:when test="${user.roleName eq '1'}">
教师
</c:when>
<c:when test="${user.roleName eq '2'}">
管理员
</c:when>
<c:otherwise>
什么玩意
</c:otherwise>
</c:choose >
<table>
<thead>
<tr>
<th>账号</th>
<th>密码</th>
<th>角色</th>
</tr>
</thead>
<tbody>
<tr>
<td>
${user.username}
</td>
<td>
${user.password}
</td>
<td>
<c:choose>
<c:when test="${user.roleName eq '0'}">
学生
</c:when>
<c:when test="${user.roleName eq '1'}">
教师
</c:when>
<c:when test="${user.roleName eq '2'}">
管理员
</c:when>
<c:otherwise>
什么玩意
</c:otherwise>
</c:choose >
</td>
</tr>
</tbody>
</table>
</body>
</html>
4.2.3 迭代标签
foreach标签
<%@ page import="com.yunhe.pojo.User" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.Random" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<%
ArrayList<User> list=new ArrayList<>();
for(int i=1;i<=20;i++){
String [] roleArr={"学生","教师","管理员"};
Random r=new Random();
list.add(new User("a"+i,"a"+i+i,roleArr[r.nextInt(roleArr.length)]));
}
session.setAttribute("list", list);
%>
<%-- foreach标签用于循环的执行与数据集合的遍历 --%>
<%-- 1、循环的书写 --%>
<c:forEach var="i" begin="0" end="10" step="2">
<%-- var用于保存循环时的变量 begin初始变量的值 end 变量结束的值 step每次循环后变量修改的大小 --%>
${i} hello world!<br>
</c:forEach>
<%-- 2、遍历数据集合 --%>
<c:forEach var="i" items="${list}" varStatus="status">
<%-- var用于保存循环时的变量 items保存遍历的数据集合 varStatus声明保存当前循环的相应信息 --%>
${i}<br>
</c:forEach>
<table>
<thead>
<tr>
<th>账号</th>
<th>密码</th>
<th>角色</th>
</tr>
</thead>
<tbody>
<c:forEach var="i" items="${list}" varStatus="status">
<tr>
<td>
${status.count}
</td>
<td>
${i.username}
</td>
<td>
${i.password}
</td>
<td>
${i.roleName}
</td>
</tr>
</c:forEach>
</tbody>
</table>
</body>
</html>