目录
1.什么是会话跟踪技术
2.Cookie
2.1.什么是cookie(如何记录用户状态)
2.2.Cookie的作用:
跟踪会话,记录⼀次会话中用户(即Session,⼀次会话可能会有多次请求,当然也可以有多个Cookie来跟踪不同的信息)的信息,这样服务器就会知道⽤户的状态,⽐如有没有登录成功,付款时购物⻋中的东⻄等,就相当于贴在客户端脑⻔上的纸条,浏览器看不到,但服务器看得到。
2.3.Cookie的应用场景
保持⽤户登录状态(免登陆)
记录⽤户名
2.4.Cookie的设置和获取
通过HttpServletResponse.addCookie的⽅式设置Cookie
Cookie cookie = new Cookie("jieguo","true");
response.addCookie(cookie);
Cookie[] cookies = request.getCookies();
if(cookies != null)
for(Cookie c : cookies){
String name = c.getName();//获取Cookie名称
if("jieguo".equals(name)){
String value = c.getValue();//获取Cookie的值
bool = Boolean.valueOf(value);//将值转为Boolean类型
}
}
2.5.删除Cookie
//1.创建⼀个name为username的Cookie
Cookie cookie = new Cookie("username", "aaa");
//2.设置Cookie的有效时间为0
cookie.setMaxAge(0);//删除cookie的关键
//3.将cookie发送给浏览器,来替换同名Cookie
response.addCookie(cookie);
2.6.设置Cookie的有效时间
//setMaxAge⽤来设置Cookie的最⼤有效时间,需要int型的参数,代表有效的秒数
cookie.setMaxAge(秒数);
//当参数⼤于0时,会设置为指定的秒数
cookie.setMaxAge(30);
//当参数等于0时,浏览器不会保存Cookie,Cookie⽴即失效
cookie.setMaxAge(0);
//当参数⼩于0时,和不设置是⼀样,当前会话有效
cookie.setMaxAge(-100);
//设置⼀个永久有效的Cookie,并⾮永久,只是使Cookie的⽣命很⻓⽽已
cookie.setMaxAge(60*60*24*365*10);
2.7.Cookie的使用
在登录页面中会弹出"是否记住用户名和密码",它是把用户名和密码存入cookie然后将cookie存入本地文件,下次再浏览该网页,就会去本地读取这个cookie,将用户名和密码在数据框中显示。达到记录用户信息效果。
要求:在登录失败后,服务器给浏览器的响应的重定向到登录页面,并把存放用户名的cookie发送浏览器,让页面显示当前的用户名,密码不建议存放到cookie.
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<%
//1.通过小脚本获取服务器传回的cookie
Cookie[] cookies = request.getCookies();
String value=null;
//2.考虑第一次访问页面时没有cookie,出现空指针异常,给个判断
if (cookies.length>0){
for (Cookie cookie : cookies) {
if (cookie.getName().equals("uname")){
value = cookie.getValue();
break;
}
}
}
//3.JSP页面中必须从域对象中获取动态数据,所以要先存值到域对象
pageContext.setAttribute("unamecookie",value);
%>
<h1>登录</h1>
<form action="/login" method="post">
用户名:<input type="text" name="username" value="${unamecookie}"><br>
密码: <input type="text" name="password"><br>
<input type="submit" value="login">
</form>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>请使用表单登录页面</h1>
</body>
</html>
success.jsp
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>登录成功</h1>
</body>
</html>
LoginServlet
package servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//接收参数
String username = req.getParameter("username");
String password = req.getParameter("password");
if ("admin".equals(username)&&"123456".equals(password)){
//登录成功,跳转,若不存着,可用重定向
resp.sendRedirect("success.jsp");
}else {
//登录失败
//1.后台创建cookie
Cookie uname = new Cookie("uname", username);
//将cookie返回给前端
resp.addCookie(uname);
resp.sendRedirect("index.jsp");
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//未使用表单提交走doGet
resp.sendRedirect("error.jsp");
}
}
3.Session
3.1.什么是Session(如何记录用户状态)
3.2.创建Session的格式
HttpSession session = request.getSession(); // 获取Session对象
session.setAttribute("loginTime", new Date()); // 设置Session中的属性
out.println("登录时间为:" +(Date)session.getAttribute("loginTime")); // 获取Session属性
3.3.Session的⽣命周期
<session-config>
<session-timeout>30</session-timeout>
</session-config>
3.4.Session常⽤⽅法:
HttpSession req.getSession()获取session对象
void setAttribute(String key,Object value) 以key/value的形式保存对象值,将数据存储在服务器端
Object getAttribute(String key) 通过key获取对象值
void invalidate() 设置session对象失效
<session-config>
<session-timeout>10</session-timeout>//单位:分钟
</session-config>
3.5.让session失效的⽅式
3.6.Sesssion的应⽤场景
代码演示:(创建Session和消除Session)
1.登录
登录后服务器使用session记录用户名,在页面显示用户名,欢迎您。
2.退出
点击退出链接后,服务器让所有session失效并重定向到登录页面
index.jsp表单登录--/login的servlet验证--跳转到success.jsp(通过session显示用户信息)--退出链接--/loginout的servlet中把session失效然后跳转到登录页面
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<%
//1.通过小脚本获取服务器传回的cookie
Cookie[] cookies = request.getCookies();
String value=null;
//2.考虑第一次访问页面时没有cookie,出现空指针异常,给个判断
if (cookies!=null&&cookies.length>0){
for (Cookie cookie : cookies) {
if (cookie.getName().equals("uname")){
value = cookie.getValue();
break;
}
}
}
//3.JSP页面中必须从域对象中获取动态数据,所以要先存值到域对象
pageContext.setAttribute("unamecookie",value);
%>
<h1>登录</h1>
<form action="/login" method="post">
用户名:<input type="text" name="username" value="${unamecookie}"><br>
密码: <input type="text" name="password"><br>
<input type="submit" value="login">
</form>
</body>
</html>
LoginServlet
package servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
@WebServlet(urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//接收参数
String username = req.getParameter("username");
String password = req.getParameter("password");
if ("admin".equals(username)&&"123456".equals(password)){
//session存值
HttpSession session = req.getSession();
session.setAttribute("username",username);
session.setAttribute("password",password);
//登录成功后设置session超时时间30分钟,也就是登录后,30分钟内没有访问页面动作
// session失效,用户再访问页面时服务器通过拦截跳转到登录页面重新登录
session.setMaxInactiveInterval(60*30);//单位是秒,设置session超时时间
//重定向或者转发时,session数据是不会丢失的,重定向时,request中的数据会丢失
resp.sendRedirect("success.jsp");
}else {
//登录失败
//1.后台创建cookie
Cookie uname = new Cookie("uname", username);
//将cookie返回给前端
resp.addCookie(uname);
resp.sendRedirect("index.jsp");
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//未使用表单提交走doGet
resp.sendRedirect("error.jsp");
}
}
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>success.jsp</h1>
当前登录用户:${sessionScope.username}<br>
<a href="/loginout">退出</a>
</body>
</html>
LoginOutServlet
package servlet;
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 java.io.IOException;
@WebServlet(urlPatterns = "/loginout")
public class LoginOutServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getSession().invalidate();//使session失效
resp.sendRedirect("index.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//super.doPost(req, resp);
}
}
服务器中设置了session的超时时间是30分钟,30分钟内随时访问localhost:8080/success.jsp页面都可以获得用户信息admin,如果设置了拦截器,这个时候是可以直接访问success.jsp,若30分钟内session没有活动,session失效,拦截器没有拿到session,用户再访问localhost:8080/success.jsp时直接跳转到登录页面要求重新登录。
3.7.Session和Cookie的区别/关系
位置上:Cookie数据保存在客户端,Session数据保存在服务器端。
安全上:Cookie存放不重要的数据,Session存放安全性的数据
关系上:Session的实现靠的是cookie携带的sessionid来识别服务器端的session存储空间。
3.8.Request和Session的区别
request存的值只能在单次请求中保存,保存的数据不能跨⻚⾯,当重定向时,request存的值会丢失
4.过滤器(Filter)
1.什么是过滤器
2.过滤器的语法格式
创建⼀个类实现Filter接⼝
public class CharSetFilter implements Filter{}
public void destroy() { //销毁的⽅法}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//过滤⽅法 主要是对request和response进⾏⼀些处理,然后交给下⼀个过滤器或Servlet处理
chain.doFilter(req, resp);
}
public void init(FilterConfig config) throws ServletException {
/*初始化⽅法 接收⼀个FilterConfig类型的参数 该参数是对Filter的⼀些配置*/
}
<filter>
<filter-name>过滤器名称</filter-name>
<filter-class>过滤器所在的路径</filter-class>
</filter>
<filter-mapping>
<filter-name>过滤器名称</filter-name>
<url-pattern>需要过滤的资源</url-pattern>
</filter-mapping>
先走哪个过滤器?
根据xml中配置的前后顺序
3.使⽤场景
3.1.防⽌⽤户未登录就执⾏后续操作
String name=(String)session.getAttribute("key");
if(name==null){
//跳转到登录⻚⾯
}
下面演示拦截器拦截未登录用户的操作以及给每个servlet统一设置编码
登录页面--过滤器1开始--过滤器2开始--过滤器2结束--过滤器1过滤未登录用户和设置编码后结束--访问通过过滤的链接
web.xml
<?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">
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<filter>
<filter-name>f1</filter-name>
<filter-class>
util.FirstFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>f1</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<%
//1.通过小脚本获取服务器传回的cookie
Cookie[] cookies = request.getCookies();
String value=null;
//2.考虑第一次访问页面时没有cookie,出现空指针异常,给个判断
if (cookies!=null&&cookies.length>0){
for (Cookie cookie : cookies) {
if (cookie.getName().equals("uname")){
value = cookie.getValue();
break;
}
}
}
//3.JSP页面中必须从域对象中获取动态数据,所以要先存值到域对象
pageContext.setAttribute("unamecookie",value);
%>
<h1>登录</h1>
<form action="/login" method="post">
用户名:<input type="text" name="username" value="${unamecookie}"><br>
密码: <input type="text" name="password"><br>
<input type="submit" value="login">
</form>
</body>
</html>
LoginServlet略,见上面
testsession.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>testsession.jsp-只有用户登录以后才能访问本页面</h1>
当前登录用户:${sessionScope.username}<br>
</body>
</html>
FirstFilter
package util;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class FirstFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("初始化filter1");//当服务器启动时执行init
}
@Override //请求和响应时都会执行这个方法
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("过滤器1开始");
//1.在.xml中设置访问任何路径走的servlet都进行处理乱码
HttpServletRequest request=(HttpServletRequest)servletRequest;
HttpServletResponse response=(HttpServletResponse)servletResponse;
request.setCharacterEncoding("utf-8");
//2.防止用户在未登录的情况下访问资源
String requestURI = request.getRequestURI();//获得请求地址
System.out.println("requestURI="+requestURI);
Object username = request.getSession().getAttribute("username");
System.out.println("过滤器获取到的session:"+username);
//若用户访问testsession.jsp且未登录,则跳转到登录页面,否则继续访问testsession.jsp页面
if(requestURI.endsWith("testsession.jsp")&&username==null){
response.sendRedirect("index.jsp");
}
//调取下一个过滤器,或者调取servlet
filterChain.doFilter(servletRequest, servletResponse);
System.out.println("过滤器1结束");
}
@Override
public void destroy() {
System.out.println("销毁filter");
}
}
LoginOutServlet见上面
若是在过滤器1中发现用户没有登录,则跳转到登录页面
登录后服务器中将用户信息存入session,此时访问http://localhost:8080/testsession.jsp是可以访问到
4.注解配置过滤器
5.监听器(Listener)
5.1.什么是监听器
5.2.监听器分类
5.3.监听三⼤域对象的创建与销毁的监听器
<listener>
<listener-class>监听器所在的路径</listener-class>
</listener>
<!--配置监听器-->
<listener>
<listener-class>util.SessionListener</listener-class>
</listener>
<listener>
<listener-class>util.AttributeListener</listener-class>
</listener>
SessionListener
package util;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/**
* 监听器
* 监听session域对象的创建销毁
*/
public class SessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
System.out.println("session创建");
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
System.out.println("session销毁");
}
}
AttributeListener
package util;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
/**
* 监听器
* 监听session域对象属性的变化
*/
public class AttributeListener implements HttpSessionAttributeListener {
@Override
public void attributeAdded(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("session存值,"+httpSessionBindingEvent.getName()+","+httpSessionBindingEvent.getValue());
}
@Override
public void attributeRemoved(HttpSessionBindingEvent httpSessionBindingEvent) {
System.out.println("session移除数据");
}
@Override
public void attributeReplaced(HttpSessionBindingEvent httpSessionBindingEvent) {
}
}
index.jsp success.jsp testsession.jsp LoginServlet LoginOutServlet上面已经有了
需要的包javaee-api-7.0.jar