session
一个用户发起的不同请求,在处理请求时,拿到同一个对象。即对象不销毁,第二次请求时,对象还在浏览器中
使用原因
Request 对象解决了一次请求内的不同 Servlet 的数据共享问题,而一个用户的不同请求的处理需要使用相同的数据使用 session 技术
使用过程
用户使用浏览器第一次向服务器发送请求,服务器在接受到请求后,调用Servlet 进行处理。给用户创建一个 session 对象,用来存储用户请求处理相关的公共数据,并将此 session 对象的 jsessionid 以 Cookie 的形式临时存储在浏览器中,用户在发起第二次请求时,请求信息中会附带 jsessionid,服务器在接收到请求后, 调用 Servlet 进行请求处理,同时根据 jsessionid 返回其对应的 session 对象
特点
- 存储在服务器端
- 服务器进行创建,每个用户独立拥有一个 session
- 依赖Cookie技术(Cookie 是浏览器端的数据存储技术)
- 一次会话
- 默认存储时间是30分钟
有效时间可以更改:
1 . 更改存储时间
2. Tomcat服务器中的web.xml中在500行左右
<!-- ==================== Default Session Configuration ================= -->
<!-- You can set the default session timeout (in minutes) for all newly -->
<!-- created sessions by modifying the value below. -->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
可以对“30”进行修改,也可以把这段话复制到项目的web.xml中
实质
解决一个用户的不同请求的数据共享问题
使用
- 创建session对象/获取session对象
HttpSession hs=req.getSession();
①如果请求中有session的标识符也就是 jsessionid,则返回其对应的session对象
②如果请求中没有session的标识符也就是 jsessionid,则创建新的session对象,并将其 jsessionid作为从cookie数据存储到浏览器内存中
③如果session对象是失效了,也会重新创建一个session对象,并将 jsessionid存储在浏览器内存中(有ID也没用,服务器把session对象删除了 ) - 设置session存储时间
hs.setMaxInactiveInterval(int seconds);
注:在指定的时间内session对象没有被使用则销毁,如果使用了则重新计时 - 设置session强制失效
hs.invalidate(); - 存储和获取数据
存储:hs.setAttribute(String name,Object value);
获取:hs.getAttribute(String name) 返回的数据类型为Object
注:
存储的动作和取出的动作发生在不同的请求中,但是存储要先于取出执行
获取数据从 session 对象,如果获取 session 中不存在的数据返回 null
使用时机
一般用户在登陆web项目时会将用户的个人信息存储到session中,供该用户的其他请求使用
注:
只要不关闭浏览器,并且 session 不失效的情况下,同一个用户的任意请求在项目的任意Servlet中获取到的都是同一个session对象
作用域
一次会话。具体来说就是,在JSESSIONID和SESSION对象不失效的情况下为整个项目内
session失效处理
将用户请求中的 jsessionid和后台获取到的session对象的 jsessionid进行比对,如果一致则session没有失效,如果不一致则证明session失效了。重定向到登录页面,让用户重新登录
注:
jsessionid存储在了Cookie的临时存储空间中,浏览器关闭即失效
总结
session解决了一个用户的不同请求的数据共享问题,只要在 jsessionid不失效和session对象不失效的情况下,用户的任意请求在处理时都能获取到同一个session对象
代码实现(1)
package com.youdian.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class SessionServlet extends HttpServlet {
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
String name="测试";
//处理请求信息
//创建session对象
HttpSession hs=req.getSession();
//设置session的存储时间——参数是秒
//hs.setMaxInactiveInterval(5);
System.out.println(hs.getId());
//设置session强制失效
//hs.invalidate();
//存储数据
hs.setAttribute("name",name);
//响应处理结果
//直接响应
resp.getWriter().write("session");
//请求转发
//重定向
}
}
获取上次代码中存储的数据内容,打印ID序列
package com.youdian.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class SessionServlet2 extends HttpServlet {
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
HttpSession hs=req.getSession();
System.out.println("SessionServlet2.service()"+hs.getId());
System.out.println("SessionServlet2.service()"+hs.getAttribute("name"));
}
}
代码实现(2)
解决“servlet——12”中的登陆后,因为重定向原因导致的ID为null的问题
具体原因说明如下:
因为在用户登录成功后使用重定向显示主页面,两次请求,而用户的信息
在第一次请求中,第二次请求中没有用户数据,所以显示为null
- 在LoginServlet中,添加Cookie信息后需要把数据存储到session对象
//将数据存储到session对象中
HttpSession hs=req.getSession();
hs.setAttribute("user",u);
完整代码如下:
package com.youdian.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.youdian.pojo.User;
import com.youdian.service.LoginService;
import com.youdian.service.impl.LoginServiceImpl;
public class LoginServlet extends HttpServlet {
protected void service(HttpServletRequest req,
HttpServletResponse resp)
throws ServletException, IOException {
//设置请求编码格式:
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
String uname=req.getParameter("uname");
//uname=new String(uname.getBytes("iso8859-1"),"utf-8");
//使用String进行数据重新编码
String pwd=req.getParameter("pwd");
System.out.println(uname+":"+pwd);
//处理请求信息
//获取业务层对象
LoginService ls=new LoginServiceImpl();
User u=ls.checkLoginService(uname, pwd);//检验 用户名密码是否在数据库存在
System.out.println(u);
//响应处理结果
if(u!=null){
//创建Cookie信息实现三天免登录。
Cookie c=new Cookie("uid", u.getUid()+"");
//设置Cookie的有效期
c.setMaxAge(3*24*3600);
c.setPath("/login/ck");
//添加Cookie信息
resp.addCookie(c);
//将数据存储到session对象中
HttpSession hs=req.getSession();
hs.setAttribute("user",u);
//重定向
//第一个/相当于localhost:8086
//或者直接写别名也可以。main
resp.sendRedirect("/login/main");
//不要用请求转发,会造成表单重复提交
// req.getRequestDispatcher("main").forward(req, resp);
// return ;
}else{
//使用request对象实现不同servlet数据流转
req.setAttribute("str", "用户名或密码错误");
//请求转发
req.getRequestDispatcher("page").forward(req, resp);
return ;
}
}
}
- 在登陆成功页面main中加入存入的对象,并且打印名称,加入form表单
//获取session中的数据
User u=(User) req.getSession().getAttribute("user");
resp.getWriter().write("<h3>欢迎"+u.getUname()+"访问我的系统</h3>");
//---
resp.getWriter().write("<hr>");
resp.getWriter().write("<form action='show' method='get'>");
resp.getWriter().write("<input type='submit' value='查看个人信息'>");
resp.getWriter().write("</form>");
完整代码如下:
package com.youdian.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.youdian.pojo.User;
public class MainServlet extends HttpServlet {
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
//获取session中的数据
User u=(User) req.getSession().getAttribute("user");
//处理请求信息
//响应处理结果
resp.getWriter().write("<html>");
resp.getWriter().write("<head>");
resp.getWriter().write("</head>");
resp.getWriter().write("<body>");
resp.getWriter().write("<h3>欢迎"+u.getUname()+"访问我的系统</h3>");
resp.getWriter().write("<hr>");
resp.getWriter().write("<form action='show' method='get'>");
resp.getWriter().write("<input type='submit' value='查看个人信息'>");
resp.getWriter().write("</form>");
resp.getWriter().write("</body>");
resp.getWriter().write("</html>");
}
}
- 在免登录时间内,如果UID存在,需要在重定向之前把数据存储到session对象中
if(u!=null){
//将用户数据存储到session对象中
req.getSession().setAttribute("user",u);
//重定向
resp.sendRedirect("/login/main");
return;
}
完整代码如下:
package com.youdian.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.youdian.pojo.User;
import com.youdian.service.LoginService;
import com.youdian.service.impl.LoginServiceImpl;
public class CookieServlet extends HttpServlet {
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
//获取Cookie信息
Cookie[] cks=req.getCookies();
//处理请求信息
if(cks!=null){
//遍历Cookie信息
String uid="";
for(Cookie c:cks){
if("uid".equals(c.getName())){
uid=c.getValue();
}
}
//校验UID是否存在
if("".equals(uid)){
//请求转发
req.getRequestDispatcher("page").
forward(req, resp);
return;
}else{
//校验UID用户信息
//获取业务层对象
LoginService ls=new LoginServiceImpl();
User u=ls.checkUidService(uid);
if(u!=null){
//将用户数据存储到session对象中
req.getSession().setAttribute("user",u);
//重定向
resp.sendRedirect("/login/main");
return;
}else{
//请求转发
req.getRequestDispatcher("page").forward(req, resp);
return;
}
}
}else{
//响应处理结果
//请求转发
req.getRequestDispatcher("page").forward(req, resp);
return;
}
}
}
- 建立新的页面show,该页面是main进行查看个人信息,点击后显示。获取请求信息后不为null,就显示个人信息
package com.youdian.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.youdian.pojo.User;
public class ShowServlet extends HttpServlet {
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
HttpSession hs=req.getSession();
if(hs.getAttribute("user")==null){
//重定向
resp.sendRedirect("/login/ck");
return;
}
User u=(User) hs.getAttribute("user");
//处理请求信息
//响应处理结果
resp.getWriter().write("<html>");
resp.getWriter().write("<head>");
resp.getWriter().write("</head>");
resp.getWriter().write("<body>");
resp.getWriter().write("<table border='1px'>");
resp.getWriter().write("<tr>");
resp.getWriter().write("<td>用户名</td>");
resp.getWriter().write("<td>"+u.getUname()+"</td>");
resp.getWriter().write("</tr>");
resp.getWriter().write("<tr>");
resp.getWriter().write("<td>密码</td>");
resp.getWriter().write("<td>"+u.getPwd()+"</td>");
resp.getWriter().write("</tr>");
resp.getWriter().write("</table>");
resp.getWriter().write("</body>");
resp.getWriter().write("</html>");
}
}