6、Session
会话技术
服务器无法识别每一次HTTP请求的出处(不知道来自于哪个终端),它只会接收到一个请求信号,所以就存在一个问题:将用户的响应发送给其他人,必须有一种技术来让服务器知道请求来自哪里,这就是会话技术。
会话:就是客户端和服务器之间发生的一系列连续的请求和响应的过程。 具体来讲就是打开浏览器操作到关闭浏览器的过程。
会话状态:指的是服务器和浏览器在会话过程中产生的状态信息,借助于会话状态,服务器能够把属于同一次会话的系列请求和响应关联起来。
实现会话有2种方式:
- session(存储于服务器内部的数据,属于Java对象)
- cookie(存储于客户端的数据,不属于Java对象,用户可手动清理)
属于同一次会话的请求都有一个相同的标识符,即SessionID。
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<title>JSP - Hello World</title>
</head>
<body>
<%
String sessionId = session.getId();
%>>
//> 423E3631E923D3B2E4F9FFF2B83F5AAD
<%=sessionId%>
</body>
</html>
常用方法
- String getId(); //获取sessionID
- void setMaxInactiveInterval(int interval) //设置session的失效时间,单位为秒
- int getMaxInactiveInterval() //获取session的失效时间,单位为秒
- void invalidate(); //设置session立即失效
- void setAttribute(String key,Object value) //通过键值对形式来存储数据,也可修改
- Object getAttribute(String key) //通过键值对获取对应的数据
- void removeAttribute(String key) //通过key删除对应的数据
一个小案例
```java package com.simon.methodtest;
import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException;
//注意,这个“/”是指部署根目录对应的路径,即localhost:8080这一级 @WebServlet(“/login”) public class LoginServlet extends HttpServlet { String myusername; String mypassword;
@Override
public void init(ServletConfig config) throws ServletException {
myusername = config.getInitParameter("username");
mypassword = config.getInitParameter("password");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//把这些参数赋值给默认初始化参数
String username = req.getParameter("username");
String password = req.getParameter("password");
if (username.equals(myusername)&&password.equals(mypassword)){
HttpSession session = req.getSession();
session.setAttribute("username",username);
// req.setAttribute(“username”,username); req.getRequestDispatcher(“welcome.jsp”).forward(req,resp); }else { resp.sendRedirect(“login.jsp”); } } }
```html
<%--
Created by IntelliJ IDEA.
User: Simon
Date: 2021/11/4
Time: 22:33
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/login" method="post">
<table>
<tr>
<td>
用户名:
</td>
<td>
<input type="text" name="username">
</td>
</tr>
<tr>
<td>
密码:
</td>
<td>
<input type="password" name="password">
</td>
</tr>
<tr>
<td>
<input type="submit" value="登录">
</td>
</tr>
<tr>
<td>
<input type="reset" value="重置">
</td>
</tr>
</table>
</form>
</body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>com.simon.methodtest.LoginServlet</servlet-class>
<init-param>
<param-name>username</param-name>
<param-value>admin</param-value>
</init-param>
<init-param>
<param-name>password</param-name>
<param-value>123123</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
</web-app>
<%--
Created by IntelliJ IDEA.
User: Simon
Date: 2021/11/4
Time: 23:47
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>Welcome</h1>
欢迎回来
//<%=request.getAttribute("username")%>
//在哪里存就从哪里取
<%=session.getAttribute("username")%>
</body>
</html>
7、Cookie
简述
Cookie是服务端在HTTP响应种附带传给浏览器的一个小文本文件,一旦浏览器保存了某个cookie,在之后的请求喝响应过程中,会将此cookie来回传递,这样就可以通过cookie这个载体完成客户端和服务端之间的数据交互。
在Java中,我们操作cookie的就是Cookie类。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
Cookie cookie = new Cookie("name", "zs");
response.addCookie(cookie);
Cookie[] cookies = request.getCookies();
for (Cookie cookie1 : cookies) {
System.out.println(cookie1.getName() + "<br/>");
}
// name<br/>
// JSESSIONID<br/>
// name<br/>
// JSESSIONID<br/>
%>
</body>
</html>
click twice;
这实际上是因为 response.addCookie(cookie); 之后,服务器响应给客户端。所以如果是第一次响应的话,请求头的Cookie内容是:JSESSIONID=0164843B17132FC86DA43118A4EFA4C5,响应头Set-Cookie为:name=zs;第二次响应的话,request会携带响应头带来的Cookie给服务器,这时候的请求头就会加上name=zs,而响应头的cookie则会覆盖请求头的内容,以此类推。
常用方法
void setMaxAge(int age) 设置Cookie的有效时间,单位为秒
int getMaxAge() 获取Cookie的有效时间
String getName() 获取Cookie的name
String getValue() 获取Cookie的value
Session和Cookie的区别
session | cookie | |
---|---|---|
数据保存位置 | 服务器 | 客户端 |
生命周期 | 随会话结束而销毁 | 长期保存,与会话无关 |
保存数据类型 | Object类型 | 文本信息 |
保存的数据重要性 | 重要 | 不重要 |
8、JSP内置对象的作用域
jsp内置对象这里重点讲4个:page、request、session、application。因为这四个都有getAttribute()和setAttribute()方法。
重点内置对象
page作用域:对应的内置对象是pageContext;
request作用域:对应的内置对象是request;
session作用域:对应的内置对象是session;
application作用域:对应的内置对象是application。
page < request < session < application:
page只在当前页面有效;
request在一次请求内有效;
session在一次会话内有效;
application对应的是整个web应用
案例:记录网站浏览人数
<%--
Created by IntelliJ IDEA.
User: Simon
Date: 2021/11/5
Time: 16:53
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
Integer count = (Integer) application.getAttribute("count");
if (count == null){
count = 1;
application.setAttribute("count",count);
}else {
count++;
application.setAttribute("count",count);
}
%>
您是当前第<%=count%>位访客!
</body>
</html>
效果:
9、EL表达式
Expression Language,表达式语言,可替代jsp页面中数据访问时的复杂编码。可以非常便捷地取出域对象中保存的数据,前提是要先setAttribute,EL就相当于在简化getAttribute。
域对象默认查找顺序
EL表达式对于4种域对象的查找顺序:pageContext—>request—>session—>application。同名下找到立即返回,在application也没找到,就返回为null。
指定作用域查找
pageContext:${pageContext.name}
request:${requestScope.name}
session:${sessionScope.name}
application:${applicationScope.name}
语法格式
语法:${变量名}
//el.jsp文件
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
request.setAttribute("name","tom");
request.getRequestDispatcher("el2.jsp").forward(request,response);
%>
</body>
</html>
//el2.jsp文件
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--//常规方式:--%>
<%
String name = (String) request.getAttribute("name");
%>
<%=name%>
<hr/>
<%--EL表达式--%>
${name}
</body>
</html>
效果如下:
数据级联
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
User user = new User(1, "zs", 86.5, "杭州市");
System.out.println(user.toString());
pageContext.setAttribute("user",user);
%>
<table>
<tr>
<th>编号</th>
<th>姓名</th>
<th>成绩</th>
<th>地址</th>
</tr>
<tr>
//可读也可写,一般是读,跟属性类的方法绑定的
<td>${user.id}</td>
<td>${user.name}</td>
<td>${user.score}</td>
<td>${user.address}</td>
</tr>
</table>
</body>
</html>
EL执行表达式
&& || ! < > <= >= ==
&& and
|| or
! not
== eq
!= ne
< lt
> gt
<= le
>= gt
empty 变量为null,长度为0的String,size集合为0