会话:访问浏览器,访问web服务器的资源,建立会话,直到有一方断开连接,会话结束。
注意:在同一会话中,可以包含多次请求
同一窗口发起多次请求,产生多次响应是同一会话
不同浏览器之间是不同会话
会话跟踪技术通过什么方式实现
服务端技术:Session
客户端技术:Cookie
Cookie:是客户端技术,可以将数据存储到客户端,然后每次请求访问的时候,都会携带 Cookie 数据访问。
如何创建 Cookie 对象
Cookie cookie = new Cookie(String name, String value)
响应Cookie 给客户端
void addCookie(Cookie cookie)
Parameters:
cookie - the Cookie to return to the client
获取 Cookie
Cookie[] getCookies()
Returns:
an array of all the Cookies included with this request, or null if the request has no cookies
Cookie 常用方法
String getName()
String getValue()
试一试
添加依赖
javax.servlet
javax.servlet-api
3.1.0
provided
javax.servlet
jsp-api
2.0
provided
jstl
jstl
1.2
taglibs
standard
1.1.2
编写 servlet
@WebServlet("/respCookie")
public class RespCookieServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie cookie = new Cookie("username", "sy");
resp.addCookie(cookie);
}
}
获取 Cookie
@WebServlet("/reqCookie")
public class ReqCookieServlet extends HttpServlet {
public static final String USER_NAME = "username";
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie[] cookies = req.getCookies();
for (Cookie cookie : cookies) {
if(ReqCookieServlet.USER_NAME.equals(cookie.getName())){
System.out.println("当前用户用户名为:"+cookie.getValue());
}
}
}
}
原理分析图
请求 RespServlet ,添加了cookie 响应数据(username:sy),响应给浏览器
得到 Cookie 值之后,会将数据存储到缓存里面的Cookie 中(浏览器不一样名称也不太一样)
从 server(服务端) 就可以通过 getCookies 获取所有的 Cookie
新打开一个浏览器已经不能使用Cookie
记住密码的功能是有时间限制的
设置 Cookie 存活时间
public void setMaxAge(int expiry)
设置0 :删除 Cookie
Cookie cookie = new Cookie("username", "sy");
cookie.setMaxAge(0);
Cookie cookie = new Cookie("username", "sy");
cookie.setMaxAge(24*60*60);
负数:关闭浏览器就没
Cookie cookie = new Cookie("username", "sy");
cookie.setMaxAge(-1);
Session:服务端会话跟踪技术,将数据保存到服务端。
Session 和 Cookie 存储区别
Cookie 存储到 client,容易被钓鱼网站拿过去用,有安全隐患
Session 存储到 Server,会相对安全
可以实现数据共享(存储会话请求的 Session ,每一次请求都可以调用(没有过期))
获取 Session 对象(如果第一次请求没有,就创建一个)
HttpSession getSession()
Returns the current session associated with this request, or if the request does not have a session, creates one.
共享数据
设置值进 Session 中
void setAttribute(String name,
Object value)
从 Session 中取值
Object getAttribute(String name)
从 Session 中删除属性
void removeAttribute(String name)
试一试
编写三个Servlet
@WebServlet("/reqSession")
public class ReqSession extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取session对象
HttpSession session = req.getSession();
//做数据共享
session.setAttribute("age",18);
}
}
@WebServlet("/respSession")
public class RespSession extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取session对象
HttpSession session = req.getSession();
//做数据共享
Object age = session.getAttribute("age");
System.out.println("==============获取req 里面设置到 session 中的值");
System.out.println(age);
}
}
@WebServlet("/removerSession")
public class RemoverSession extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取session对象
HttpSession session = req.getSession();
session.removeAttribute("age");
}
}
Session 是基于 Cookie 实现的
原理分析图
文字说明
请求ReqServlet 会得到一个 Cookie (JSESSIONID=1)
生成一次会话 session 存储到服务端(JSESSIONID=1)
再次请求 RespServlet 的时候,会携带上 JESSIONID =1 去找到我们的 Session 对象
分析以下 session 使用可能出现的问题
第一次请求获取的Session存储到服务器之后
此时公司内部重启服务器
第二次去访问的时候,Session 已经不存在了
很影响用户体验感
钝化与活化的目的
为了存储session,保证正常关闭下正常启动的时候,同一会话有效
演示钝化与活化
钝化
服务器正常关闭的时候,tomcat 会把 session 数据写入硬盘work 目录下(sessions.ser文件)
活化
服务器启动的时候,tomcat 读取 sessions.ser 中的数据,并且删掉这个文件(删掉的目的是为了减少不需要的钝化文件污染磁盘,造成磁盘空间的浪费)
分为两种方式:自动销毁和手动销毁
自动销毁
默认情况下无操作 30分钟
Archetype Created Web Application
33333
手动销毁
void invalidate()
Invalidates this session then unbinds any objects bound to it.
@WebServlet("/reqSession")
public class ReqSession extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取session对象
HttpSession session = req.getSession();
//做数据共享
session.setAttribute("age",18);
session.invalidate();
}
}
Cookie 与 Session 作用:用来在会话中做数据共享,存储数据。
不同点 | Cookie | Session |
---|---|---|
存储位置 | client | server |
存储时间 | setMaxAge()可以长期存储 | 默认30分钟 |
存储数据大小 | 最大3KB | 无限制 |
安全性 | 不安全 | 安全 |
服务器性能影响 | 不占用服务器资源 | 占用服务器资源 |
应用场景 | Cookie | Session |
---|---|---|
记住密码 | 使用Cookie | |
验证码 | 使用Session | |
登录名称 | Session | |
购物车 | 使用Cookie |
servlet 获取前端传送的 username 和 password 数据
拷贝 jdbcUtil 工具类,将得到的数据和数据库比较(以三层架构的方式去做)
响应给浏览器
记住账号密码功能需要响应 cookie
验证码功能需要设置 session
登录成功之后,跳转到index.jsp 页面,并且用 h1 标签显示当前登录的用户信息
@WebServlet("/csLogin")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username);
System.out.println(password);
ILoginService service = new LoginServiceImpl();
User user = service.login(username, password);
if(user == null){
System.out.println("没有登录成功");
req.getRequestDispatcher("/login.html").forward(req,resp);
}else{
HttpSession session = req.getSession();
session.setAttribute("user",user);
resp.sendRedirect("/index.jsp");
}
}
}
public class LoginServiceImpl implements ILoginService {
@Override
public User login(String username, String password) {
User domain = JDBCUtil.getDomain(JDBCUtil.getConn(),
"select * from user where username = ? and password = ?", User.class, username, password);
return domain;
}
}
@WebServlet("/csLogin")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
String remember = req.getParameter("remember");
String checkCode = req.getParameter("checkCode");
HttpSession session = req.getSession();
if ("on".equals(remember)) {
//创建 cookie
Cookie usernameCookie = new Cookie("username", username);
Cookie passwordCookie = new Cookie("password", password);
Cookie rememberCookie = new Cookie("remember", "on");
//发送 cookie
resp.addCookie(usernameCookie);
resp.addCookie(passwordCookie);
resp.addCookie(rememberCookie);
} else {
// Cookie[] cookies = req.getCookies();
// for (Cookie cookie : cookies) {
// if("username".equals(cookie.getName()) || "password".equals(cookie.getName())){
// cookie.setValue("");
// }
// }
}
System.out.println(username);
System.out.println(password);
String ret = (String) session.getAttribute("checkCode");
if (!ret.equalsIgnoreCase(checkCode)) {
req.setAttribute("check_msg", "验证码错误");
req.getRequestDispatcher("/login.jsp").forward(req, resp);
return;
}
ILoginService service = new LoginServiceImpl();
User user = service.login(username, password);
if (user == null) {
System.out.println("没有登录成功");
req.getRequestDispatcher("/login.jsp").forward(req, resp);
} else {
session.setAttribute("user", user);
resp.sendRedirect("/index.jsp");
}
}
}
@WebServlet("/checkCode")
public class CheckCoderServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//生成验证码
String code = VerifyCodeUtil.outputVerifyImage(500, 200, resp.getOutputStream(), 4);
//存储到 session 方便验证
HttpSession session = req.getSession();
session.setAttribute("checkCode",code);
}
}