1.Session概述
1、在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),
注意:一个浏览器独占一个session对象(默认情况下)。
2、Session 是一个域
1.作用范围:一个浏览器和服务器会话范围
2.生命周期:
创建
当程序第一次调用到request.getSession()方法时说明客户端明确的需要用到session此时创建出对应客户端的Session对象.
request.getSession()=request.getSession(true),有session返回,没就创建。
request.getSession(false):有session直接返回,没session返回null,不创建
销毁
2.1当session超过30分钟(这个时间是可以在web.xml文件中进行修改的)没有人使用则认为session超时销毁这个session.
2.2程序中明确的调用session.invalidate()方法可以立即杀死session.
2.3.当服务器被非正常关闭时,随着虚拟机的死亡而死亡.
钝化
*如果服务器是正常关闭,还未超时的session会被以文件的形式保存在服务器的work目录下,这个过程叫做session的钝化.
活化
*下次再正常启动服务器时,钝化着的session会被恢复到内存中,这个过程叫做session的活化.
3.作用:在会话范围内共享数据。
web.xml文件中进行修改session时间
根目录下配置 <session-config> <session-timeout>30 </session-timeout> </session-config>
session 的原理:
1、request.getSession()方法会检查请求中有没有JSESSIONID cookie,如果有拿出他的值找到对应的session为他服务.
2、如果JSESSIONID cookie没有,则检查请求的URL后有没有以拼接JSESSIONID过来,如果有,则根据JSESSIONID的值找到对应的Session为浏览器服务。
3、如果还找不到JSESSIONID,则认为这个浏览器没有对应的Session,创建一个Session然后再在响应中添加JSESSIONID cookie
4、默认情况下,JSESSIONID 的path为当前web应用的名称,并且没有设置过MaxAge,是一个会话级别的cookie.
5、这意味着一旦关闭浏览器再新开浏览器时,由于JSESSIONID丢失,会找不到之前的Session
6、我们可以手动的发送JSESSIONID cookie,名字和path设置的和自动发送时一样,但是设置一下MaxAge,使浏览器除了在内存中保存JSESSIONID信息以外还在临时文件夹中以文件的形式保存,这样即使重开浏览器仍然可以使用之前的session
URL重写:
1、如果浏览器禁用了Cookie,浏览器就没有办法JSESSIONID cookie,这样就用不了Session了.
2、我们可以使用URL重写的机制,在所有的超链接后都以参数的形式拼接JSESSIONID信息,从而在点击超链接时可以使用URL参数的方式带回JSESSIONID,从而使用Session
3、将URL进行重写拼接上JSESSIONID的过程就叫做URL重写
4、request.getSession()
在URL重写之前一定要先创建出Session,才有Session id,才能进行重写
5、response.encodeURL()
一般的地址都用这个方法重写
6、response.encodeRedirectURL()
如果地址是用来进行重定向的则使用这个方法
7、*url重写的方法一旦发现浏览器带回了任意cookie信息,则认为客户端没有禁用cookie,就不会再进行重写操作
总结cookie和session
1.cookie是客户端技术
1、数据保存在客户端,这个信息可以保存很长时间
2、数据随时有可能被清空,所以cookie保存的数据是不太靠谱的
3、数据被保存在了客户端,随时有可能被人看走,如果将一些敏感信息比如用户名密码等信息存在cookie中,可能有安全问题
2.session是服务器端技术
1、数据保存在服务区端,相对来说比较稳定和安全
2、占用服务器内存,所以一般存活的时间不会太长,超过超时时间就会被销毁.我们要根据服务器的压力和session 的使用情况合理设置session的超时时间,既能保证session的存活时间够用,同时不用的session可以及时销毁减少对服务器内存的占用.
Session案例_登录注销
UserDao.jsp
private UserDao(){} private static Map<String, String> userMap = new HashMap<String, String>(); static{ userMap.put("张三", "333"); userMap.put("李四", "444"); userMap.put("王五", "555"); } public static boolean ValiNP(String username,String password){ return userMap.containsKey(username)&& userMap.get(username).equals(password); }
index.jsp
//获取session中的登录状态 String user = (String)session.getAttribute("user"); if(user==null||"".equals(user)){ 登录,注册 }else{ 注销 }
login.jsp
<h1>用户登录</h1> <form action="${pageContext.request.contextPath}/servlet/LoginServlet" method="POST"> 用户名:<input type="text" name="username"/> 密码:<input type="password" name="password"/> <input type="submit" value="登录"/> </form>
LoginServlet.java
request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); //1.获取请求参数的名字和密码 String username = request.getParameter("username"); String password = request.getParameter("password"); //2.检查 if(UserDao.ValiNP(username, password)){ //3.将名字和密码设置到session中 HttpSession session = request.getSession(); session.setAttribute("user", username); //4.回主页 response.sendRedirect(request.getContextPath()+"/logout/index.jsp"); //5.记得写return 后面的代码不用执行 return; }else{ response.getWriter().write("用户名,密码不正确"); }
LogoutServlet.java
//有session直接返回,没session返回null,不创建 HttpSession session = request.getSession(false); if(session!=null&& session.getAttribute("user")!=null){ session.removeAttribute("user"); } response.sendRedirect(request.getContextPath()+"/logout/index.jsp");Session案例_防止表单重复提交
resubIndex.jsp
<script type="text/javascript"> var isNotSub = true; function canSub(){ //客户端提示 if(isNotSub){ isNotSub = false; return true; }else{ alert("请不要重复提交!!!"); return false; } } </script>
<% Random r = new Random(); int valinum = r.nextInt(); session.setAttribute("valinum",valinum+""); %>
<form action="${pageContext.request.contextPath }/servlet/ResubServlet" method="POST" onsubmit="return canSub()"> //客户端提示 用户名:<input type="text" name="username"/> <input type="hidden" name="valinum" value="<%=valinum %>"/> //服务端提示 <input type="submit" value="注册"/> </form>
ResubServlet.java
String username = request.getParameter("username"); String valinum = request.getParameter("valinum"); String valinum2 = (String) request.getSession().getAttribute("valinum"); if(valinum2!=null && !"".equals(valinum2) && valinum.equals(valinum2)){ request.getSession().removeAttribute("valinum"); //提交表单,页面未跳转的时候,同一个浏览器,第一次带着的session和请求参数valinum与第二次请求参数valinum是一致的,第二次的session为null? System.out.println("向数据库中注册一次:"+username); }else{ response.getWriter().write("from web:不要重复提交!!"); } }