Session会话简介与基本知识点

当浏览器第一次访问服务器时,无论先访问哪一个页面,服务器就会给用户分配一个唯一的会话标识,即jsessionid然后以cookie的形式返回给用户。

会话是指在一段时间内,用户使用同一个浏览器进程与Web应用之间的交互过程。

会话(Session)通常用来跟踪用户的状态,缓存用户在此浏览器进程中的信息。

当用户关闭浏览器,上一个Session也就无法再次获得了(Cookie的maxAge为-1的情况)。再次打开新的浏览器,将开始一个新的会话。

类javax.servlet.http.HttpSession。每一个HttpSession代表用户的一个会话。

每一个Session的过期时间默认为30分钟。

服务器给每个用户创建一个会话,即HttpSession对象,保存在服务器端。

那么,当用户再次访问服务器时,服务器是如何知道还是当前用户呢?

当浏览器再次访问服务器时,会携带包含了jsessionid的cookie访问服务器。服务器根据此id返回此用户的HttpSession对象,就保持了会话。

每一个Session都一个唯一标识,即ID。

当浏览器获取一个新的Session时,用户即可以通过session.geId();打印出ID的值 。

再不关闭浏览器的情况下,在多个页面上跳转,使用的是同一个Session。

画图演示:

1、演示request,session,servletContext这3个容器:

index.jsp:

<h1>演示session技术</h1>
<h2>演示request,session,servletContext这3个容器</h2>
<form action="SaveServlet" method="post">
name:<input type="text" name="name"/>&nbsp;&nbsp;
<input type="submit" />
</form>
<br/>
<a href="GetServlet">读取这3个容器中的数据</a>

web.xml:

<servlet>
<servlet-name>SaveServlet</servlet-name>
<servlet-class>cn.hncu.servlets.session.SaveServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>GetServlet</servlet-name>
<servlet-class>cn.hncu.servlets.session.GetServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SaveServlet</servlet-name>
<url-pattern>/SaveServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>GetServlet</servlet-name>
<url-pattern>/GetServlet</url-pattern>
</servlet-mapping>

SaveServlet.java:

package cn.hncu.servlets.session;

import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class SaveServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//System.out.println("aaaaa");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
request.setCharacterEncoding("utf-8");//如果接收的字符有中文,要设这一句
String name = request.getParameter("name");
request.setAttribute("name", "request---"+name);
request.getSession().setAttribute("name", "session---"+name);
this.getServletContext().setAttribute("name", "servletContext---"+name); //把cookie技术和session技术联合起来做应用的一个例子---
//功能:让用户在关闭浏览器之后,如果5分钟之内再登陆本网站,还能访问到session
//其实原理很简单,就是向客户端写一个key为"JSESSIONID",value用sessionid的cookie
//System.out.println(request.getSession().getId());
//System.out.println(request.getSession().getAttribute("JSESSIONID"));//这个的值是null
Cookie c = new Cookie("JSESSIONID", request.getSession().getId());
c.setMaxAge(60*5);//5分钟后过期
c.setPath(request.getContextPath());//权限给本站的所有网页/servlet
//---根据客户端无论访问那个网站的哪个网页都会有JSESSIONID可以知道,这个的权限路径肯定是项目根目录下面
response.addCookie(c); out.print("<h1>保存成功!</h1>");
//System.out.println("bbbbbb");
out.close(); } }

GetServlet.java:

package cn.hncu.servlets.session;

import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class GetServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
out.println("<HTML>");
out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>");
out.println(" <BODY>"); String reqName = (String) request.getAttribute("name");
String sessName = (String) request.getSession().getAttribute("name");
String contName = (String) request.getServletContext().getAttribute("name"); out.print(reqName+"<br/>");
out.print(sessName+"<br/>");
out.print(contName+"<br/>"); out.println(" </BODY>");
out.println("</HTML>");
out.flush();
out.close();
} }

演示结果:

我再到另外一个浏览器打开:

可以看到session的name值没有了。

为了防止误关浏览器导致session访问不到的解决办法:

或者你把浏览器关了再打开,session的值也没有了!

这个时候,有的时候就会出现手误的情况,不小心把浏览器关了,着就很尴尬了,所以呢,有的网站为例预防这种情况,就可以这样来做!!!

在SaveServlet类中加上这样的代码就可以了!!

    //把cookie技术和session技术联合起来做应用的一个例子---
//功能:让用户在关闭浏览器之后,如果5分钟之内再登陆本网站,还能访问到session
//其实原理很简单,就是向客户端写一个key为"JSESSIONID",value用sessionid的cookie
System.out.println(request.getSession().getId());
System.out.println(request.getSession().getAttribute("JSESSIONID"));
Cookie c = new Cookie("JSESSIONID", request.getSession().getId());
c.setMaxAge(60*5);//5分钟后过期
c.setPath(request.getContextPath());//权限给本站的所有网页/servlet
//---根据客户端无论访问那个网站的哪个网页都会有JSESSIONID可以知道,这个的权限路径肯定是项目根目录下面
response.addCookie(c);

演示验证码-利用session传递值:

index.jsp:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<script type="text/javascript">
function get(){
var nameElement = document.getElementById("inputName");
var pwdElement = document.getElementById("inputPwd");
var cs = document.cookie.split("; ");//按分号+空格拆分
//alert(document.cookie);
var name="";
var pwd="";
for(var x=0;x<cs.length;x++){
cs[x] = decodeURI(cs[x]);
//alert(cs[x]);
var strs = cs[x].split("=");
//alert(strs);
//alert("strs[0]="+strs[0]);
//alert("strs[1]="+strs[1]);
strName=strs[0];
if(strs[0]=="name1"){
name=strs[1];
}else if(strs[0]=="pwd1"){
pwd=strs[1];
}
}
nameElement.value =name;
pwdElement.value = pwd;
//alert(name);
//alert(pwd);
} function leave(element,name){
var date = new Date();
date.setTime( date.getTime()+ 1000*60*60 );
var key = name;
var value = element.value;
value = encodeURI(value);//中文编码X
document.cookie=key+"="+value+";expires="+date.toGMTString()+";path=/";
} </script> </head> <body onload="get()"> <h2>演示验证码</h2>
<form action="session/LoginServlet" method="post">
Name:<input id="inputName" type="text" name="name" value="" onblur="leave(this,'name1');"/><br/>
Pwd:<input id="inputPwd" type="password" name="pwd" value="" onblur="leave(this,'pwd1');"/><br/>
<% Date d = new Date();
long str = d.getTime();
%>
<a href="index.jsp?time=<%=str %>"><img src="servlet/ImgServlet"/></a><input type="text" name="code"/>
<input type="submit" value="登录" />
</form> <br/><br/><br/><br/> </body>
</html>

ImgServlet.java:

package cn.hncu.servlets.session;

import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Random; import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class ImgServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { response.setContentType("image/jpg");//告诉浏览器,你发过去的数据是什么类型
int width = 60;
int height = 30;
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g = img.getGraphics();
g.setFont(new Font("宋体", Font.BOLD, 18));
Random r = new Random(new Date().getTime());
String str="";
for(int i=0;i<4;i++){
int a = r.nextInt(10);
str+=a;
int x1=r.nextInt(width);
int x2=r.nextInt(width);
int y1=r.nextInt(height);
int y2=r.nextInt(height);
g.drawLine(x1, y1, x2, y2);
}
//将生成的验证码放入session---真值
request.getSession().setAttribute("realCode", str);
g.drawString(str, 0, height); g.dispose();//把图刷到img当中去
ImageIO.write(img, "jpg", response.getOutputStream());
}
}

LoginServlet.java:

package cn.hncu.servlets.session;

import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class LoginServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
request.setCharacterEncoding("utf-8");
//从客户端获取输入的name,pwd,code
String name = request.getParameter("name");
String pwd = request.getParameter("pwd");
String code = request.getParameter("code");//这是用户输入的验证码 String realCode = (String) request.getSession().getAttribute("realCode");//后台保存的真实验证码
if(code==null || !code.equals(realCode)){
out.print("<h1>验证码错误!!!</h1>");
}else{ //这里我们因为没做数据库,假定我们只判断name和pwd,如果name和pwd相同,我们就认为他登录成功
if(name!=null&&name.trim().length()>0&&name.equals(pwd)){
out.print("<h1>欢迎回来!"+name+".</h1>");
}else{
out.print("<h1>用户名或者密码不正确!</h1>");
}
}
//这个必须要清!验证完之后清除原来旧的验证码
request.getSession().removeAttribute("realCode"); }
}

演示结果:

嘿嘿,就不演示啦,就是一个简单session传递验证~

添加了验证码和保存上一个name和密码的功能。

重写URL,安全退出:

如果浏览器不支持Cookie或用户阻止了所有Cookie,可以把会话ID附加在HTML页面中所有的URL上,这些页面作为响应发送给客户。这样,当用户单击URL时,会话ID被自动作为请求行的一部分而不是作为头行发送回服务器。这种方法称为URL重写(URL rewriting)。

何为安全登录和安全退出:

当用户登录后,一般在Session中保存有用户的信息。

Session.setAttirubte(…)

用户退出时,应该当将自己的信息从Session中清除-即安全退出。

Session.invalidate();

Session.removeAttribute(…)

index.jsp:

<h2>演示重写url技术---破解用户禁用cookie之后,我们session无效的问题</h2>
<form action="<%= response.encodeURL("SaveServlet") %>" method="post">
Name:<input type="text" name="name"/><br/>
<input type="submit"/>
</form>
<a href="<%=response.encodeURL("GetServlet") %>">重写url-读取几个容器中的数据</a></br>
<a href="<%=response.encodeURL("LogoutServlet")%>"> 重写url-安全退出 </a>
<!-- 点击上面的安全退出后,这个浏览器原来的session就会失效! -->

web.xml:

<servlet>
<servlet-name>LogoutServlet</servlet-name>
<servlet-class>cn.hncu.servlets.session.LogoutServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LogoutServlet</servlet-name>
<url-pattern>/LogoutServlet</url-pattern>
</servlet-mapping>

LogoutServlet.java:

package cn.hncu.servlets.session;

import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class LogoutServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
//安全退出,其实很简单的,只要让session对象无效就行了!-我们可以销毁服务器中的那个session对象
request.getSession().invalidate();
out.print("<h1>已经安全退出了!!!</h1>");
}
}

安全退出,一般购物网站之类隐私较多的网站用的多!

Web---session技术代码演示(request,session,servletContext)的更多相关文章

  1. {Django基础八之cookie和session}一 会话跟踪 二 cookie 三 django中操作cookie 四 session 五 django中操作session

    Django基础八之cookie和session 本节目录 一 会话跟踪 二 cookie 三 django中操作cookie 四 session 五 django中操作session 六 xxx 七 ...

  2. java web(三):ServletContext、session、ServletConfig、request、response对象

    上一篇讲了Servlet: 1)什么是Servlet[servlet本身就是一种Java类,这种Java类提供了web形式的方法,只要实现了servlet接口的类,都是一种servlet资源.] 2) ...

  3. zk 获取session,request,servletContext,response

    (参考:http://www.dotblogs.com.tw/rockywang/archive/2010/01/13/12995.aspx) HttpServletRequest request = ...

  4. Struts2初学 Struts2在Action获取内置对象request,session,application(即ServletContext)

    truts2在Action中如何访问request,session,application(即ServletContext)对象???? 方式一:与Servlet API解耦的方式      可以使用 ...

  5. 域对象 pageContext request session servletContext

    pageContext 当前页面之内有效 request   当前的请求内有效 session 当前的会话内有效 servletContext 当前这次服务器生命周期内有效

  6. Java web 会话技术 cookie与session

    一.会话 会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话. 会话过程中要解决的一些问题 每个用户在使用浏览器与服务器进行会话的过程 ...

  7. java web作用域page request session application

    转载自:http://blog.csdn.net/wyd458549392147/article/details/6944481 1.page指当前页面.只在一个jsp页面里有效 . 2.reques ...

  8. web开发中的Cookie与Session技术

    Cookie Cookie的由来 HTTP协议是无状态的,无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不会直接影响后 ...

  9. JAVAWEB开发之JSP、EL、及会话技术(Cookie和Session)的使用详解

    Servlet的缺点 开发人员要十分熟悉JAVA 不利于页面调试和维护(修改,重新编译) 很难利用网页设计工具进行页面设计(HTML内容导入到servlet中,用PrintWriter的对象进行输出) ...

随机推荐

  1. Dao模型设计(基于Dao与Hebernate框架)

    以前没有Dao设计模型之前,一般都是这样的流程: ①先设计实体对象 学生对象: package com.itheima.domain; import java.io.Serializable; imp ...

  2. Codevs 3233 古道

    3233 古道 时间限制: 1 s 空间限制: 8000 KB 题目等级:**白银 Silver** [传送门](http://codevs.cn/problem/3233/) 题目描述 Descri ...

  3. (LightOJ 1004) Monkey Banana Problem 简单dp

    You are in the world of mathematics to solve the great "Monkey Banana Problem". It states ...

  4. IniParse解析类

    说明 iniParse这个类是一个解析ini文件的类,他的功能和Windows下GetPrivateProfileString的功能一样,可以很方便的保存读取配置. 当然他不是只有GetPrivate ...

  5. 静态库的pdb

    静态库也会有pdb,只不过,默认是以vc编译器作为名字,比如vs2003的lib的pdb是vc70.pdb,vs2008则是vc90.pdb

  6. iframe框根据内容自适应高度

    1.页面 <iframe name="iframe_userCenter" id="iframe" frameborder=2 width=100% he ...

  7. DataTable操作(建表,建行,建列,添加数据)

    public DataTable GetNewTable() { DataTable dt2 = new DataTable("NewDataSet"); //创建一个新Table ...

  8. Mysql DOC阅读笔记

    Mysql DOC阅读笔记 转自我的Github Speed of SELECT Statements 合理利用索引 隔离调试查询中花费高的部分,例如函数调用是在结果集中的行执行还是全表中的行执行 最 ...

  9. Record:逻辑分区下新建简单卷后其他卷被删除

    上图是恢复后的磁盘情况,恢复前的情况没有截图. 事情是这样:扩展分区中原本有4个逻辑分区.想将其中一个分区(MySpace,第一个分区)压缩出部分空间新建一个分区.经过 压缩卷->新建简单卷 后 ...

  10. 尝试使用Java6API读取java代码

    主要类:JavaCompiler  FileManager JavaCompiler .CompilationTaskAbstractProcessor参考代码https://today.java.n ...