在学习完了Servlet中的Cookie技术后,我们再来学习另一个能保存会话数据的技术——Session。

  Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,注意是默认情况下,一个浏览器独占一个session,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自数据存放在各自的session中,当用户再去访问服务器的其他web资源时,其他web资源再从用户各自的session中取出数据为用户服务。

Session和Cookie的主要区别:

  Cookie技术是客户端技术,是由服务器将用户的数据写回给用户浏览器的。
  Session技术是服务器端技术,是把用户的数据写到服务器为用户所创建的独享的Session对象中,但Session是基于Cookie的(请看下一篇《Servlet的学习之Session(2)》)。

  Session对象由服务器创建,这跟Cookie不一样。编程人员可以通过request请求对象的getSession()方法获取Session对象。

  注意,Session一旦创建,是会存活无操作情况(或者浏览器关闭)下30分钟,这是由服务器(如Tomcat)来指定的。当我们关闭浏览器后,因为Session是基于cookie的,因此Session是存在的,只是我们可能无法再使用到(要看cookie是否还能取到)。

  那么我们以一个简单的Session例子来说明,创建两个Servlet:分别命名为ServletDemo1和ServletDemo2。

在ServletDemo1中的代码如下:

 HttpSession session = request.getSession();
String data = "message form SessionDemo1";
session.setAttribute("data", data);

在ServletDemo2中的代码如下:

 response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter(); HttpSession session = request.getSession();
String data = (String) session.getAttribute("data");
writer.write(data);

  当我们打开一个浏览器先访问ServletDemo1,此时浏览器会帮我们创建Session对象,并保存数据,这时再访问ServletDemo2可以看到该保存的数据:

  

  说明Session确实能保存访问不同Servlet时的数据。

  这里说清楚一点,虽然代码都是相同的,但是针对不同浏览器访问的话看到的是不同的Session对象保存的不同的数据,虽然这时候数据都是一样的。比如说A在自己主机上访问这个Servlet和B在自己电脑上访问这个相同的Servlet,A和B得到各自的Session。

  而如果我们打开一个浏览器访问ServletDemo1后,再打开另一个浏览器访问ServletDemo2,那么则会显示该数据找不到:

  

注意:这时候是两个浏览器,即已经是两个会话了!!!

  我们来做一个类似于点击商品然后能加入到购物车的案例,使用Session技术。

前提准备,我们需要为商品创建JavaBean,代码如下:

 public class Product {
private String id;
private String name;
private String author; public Product() {
super();
} public Product(String id, String name, String author) {
super();
this.id = id;
this.name = name;
this.author = author;
} public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getAuthor() {
return author;
} public void setAuthor(String author) {
this.author = author;
}

然后再建立一个数据库,以类的方式来创建(谁让数据库还没学呢T_T!),然后使用Map集合来存储数据,便于通过键值对检索:

 public class ProductDatabase {

     private static Map<String,Product> map = new HashMap<String,Product>();

     static{
map.put("1", new Product("1","《Java编程思想》","JB"));
map.put("2", new Product("2","《Java核心技术》","fdaf"));
map.put("3", new Product("3","《Java并发编程》","什么鬼"));
map.put("4", new Product("4","《Head first 设计模式》","老王"));
map.put("5", new Product("5","《HTML5权威手册》","hhaa"));
} public static Map<String,Product> getMap() { return map;
}
}

好了,我们在商品显示的首页显示商品,同时为每个商品建立一个超链接,以便于当用户点击超链接时能将商品的id作为存储数据的依据由其他Servlet类获取用户购买的商品种类:

   response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter(); //获取数据库中的商品数据
Map<String, Product> map = ProductDatabase.getMap();
for(Map.Entry<String, Product> entry : map.entrySet()) {
Product book = entry.getValue();
writer.print(book.getName()+" <a href='/myservlet/servlet/BuySession?id="+book.getId()+"' >购买</a> <br/>");
}

此时可以看一看效果:

  

接着我们来做 点击购买超链接后的Servlet,该Servlet需要将获取用户所购买的商品(通过id号),同时需要获取(创建)Session对象,并利用一个集合将所购买的商品存入,这个Session对象存储用户希望购买的商品,当我们跳转到购物车页面上时能从Session中取出商品并显示:

         //获取用户所购买商品的id号
String productId = request.getParameter("id");
Product book = ProductDatabase.getMap().get(productId); //将用户所购买的商品加入到Session对象中保存,以便最后一起结账,类似于购物车功能
HttpSession session = request.getSession();
List<Product> list = (List<Product>) session.getAttribute("productList");
if(list == null){
//首次购买
list = new ArrayList<Product>();
session.setAttribute("productList", list);
} list.add(book); //跳转到购物车列表上
response.sendRedirect("/myservlet/servlet/CartListServlet");

注意:这里使用的是sendRedirect重定向,如果使用的是forward转发,则在购物车页面进行刷新的话会将每次购买的商品再次购买。

在购物车页面的Servlet中功能就可以比较简单了,从用户的Session中取出保存的购买商品对象,并显示在页面上即可:

         response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter(); writer.print("您购买的商品如下: <br/>"); HttpSession session = request.getSession();
List<Product> list = (List<Product>) session.getAttribute("productList");
for(Product p : list) {
writer.write(p.getName()+"<br/>");
}

点击多个商品,会看到在购物车的Servlet页面上会显示出我们购买的商品:

  

而另外开启的多个浏览器点击这些商品会看到购买的不同购物车页面,所以可以使用Session来解决不同用户来访问相同页面而同时保存他们各自不同数据的需求。

  当然这只是一个简单的强调session对象能在一个会话过程中保存一个浏览器访问多个Servlet中会产生的数据,上面这样的简单示例肯定是不能用于购物的,比如当我们将浏览器关闭时(会话结束),这个session对象就结束了,那么下次再打开浏览器我们的购物车将一无所有,如果要满足用户的不同需求,那么就要了解一些session对象的底层结构,将在下一篇中介绍和学习。

Servlet的学习之Session(1)的更多相关文章

  1. Servlet的学习之Session(3)

    在上一篇<Servlet的学习之Session(2)>我们知道了Session能实现一个会话过程中保存数据或者多个会话中实现同一个Session的关键因素就是Cookie,只是Cookie ...

  2. Servlet的学习之Session(2)

    在上一篇中我们学习了Session对象默认在一个会话过程中,由服务器创建,能保存在这个会话过程中用户访问多个web资源时产生的需要保存的数据,并在访问服务器中其他web资源时可以将这些数据从Sessi ...

  3. Servlet的学习之Session(4)

    在本篇中,我们来使用Session完成一个用户登录的案例,前提声明:这个案例主要用于学习Session技术,是属于比较简单的类型,以后会采用MVC模式来开发登录,那就会比较复杂. 现在大多数网站都提供 ...

  4. Servlet的学习之Session(5)

    在上一篇中我们介绍了如果使用Session来做一个简单的用户登录案例,在本篇中我们继续使用Session技术来做一个防止表单重复提交的案例. 这是一个很重要的知识点,在很多框架中都有防止表单重复提交的 ...

  5. JavaWeb之Servlet:Cookie 和 Session

    会话 现实生活中我们会用手机跟对方对话,拿起手机,拨号,然后对面接听,跟着互相通话,最后会话结束. 这个过程也可以用我们的B/S模式来描述: 打开浏览器—>输入地址->发出请求->服 ...

  6. Servlet的学习之Cookie

    从本篇开始学习Servlet技术中的Cookie专题. 首先来了解什么是“会话”.会话是web技术中的一个术语,可以简单的理解为:用户打开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭 ...

  7. Servlet的学习之Filter过滤器技术(1)

    本篇将讲诉Servlet中一项非常重要的技术,Filter过滤器技术.通过过滤器,可以对来自客户端的请求进行拦截,进行预处理或者对最终响应给客户端的数据进行处理后再输出. 要想使用Filter过滤器, ...

  8. Servlet的学习(四)

    在本篇的Servlet的学习中,主要来学习由使用MyEclipse来开发Servlet的一些小细节. 细节一:在web.xml中可以对同一个Servlet配置多个对外访问路径,并如果在web.xml中 ...

  9. Servlet的学习之Request请求对象(3)

    本篇接上一篇,将Servlet中的HttpServletRequest对象获取RequestDispatcher对象后能进行的[转发]forward功能和[包含]include功能介绍完. 首先来看R ...

随机推荐

  1. [Swust OJ 1094]--中位数(巧用set,堆排序)

    题目链接:http://acm.swust.edu.cn/problem/1094/ Time limit(ms): 1000 Memory limit(kb): 32768   中位数(又称中值,英 ...

  2. hadoop -- mapreduce执行过程

    1.运行mapreduce程序  ---run2.本次运行将会生成呢个一个Job , 于是JobClient向JobTracker申请一个JobID 标识该Job.3.JobClient将Job需要的 ...

  3. C++ cout 如何保留小数输出

    参考 : http://upliu.net/how-cout-out-2-precision.html 大家都知道用 C 语言中 printf () 函数可以非常方便控制保留 几位小数输出 不过在 C ...

  4. eclipse中build workspace的相关优化

    网上流传的各种的eclipse的调优的方法都大同小异,但是调优的基本上针对eclipse或者myclipse的本身,比如关掉validate和启动项,文件拼写,和自动构建等,调过之后,等个eclips ...

  5. Linux内核空间-用户空间通信之debugfs

    一.debugfs文件系统简介 debugfs虚拟文件系统是一种内核空间与用户空间的接口,基于libfs库实现,专用于开发人员调试,便于向用户空间导出内核空间数据(当然,反方向也可以).debugfs ...

  6. VC++的内联汇编

    1.移植性差,假设是软件项目建议不要用.假设希望一段程序仅在单一设备上执行而且效率极高,能够使用内联汇编. 比方.单片机开发. 2. ......持续更新中. .... .

  7. BZOJ 3211: 花神游历各国( 线段树 )

    线段树...区间开方...明显是要处理到叶节点的 之前在CF做过道区间取模...差不多, 只有开方, 那么每个数开方次数也是有限的(0,1时就会停止), 最大的数10^9开方10+次也就不会动了.那么 ...

  8. Qt 多线程与数据库操作需要注意的几点问题

    源地址:http://blog.csdn.net/goldenhawking/article/details/10811409 彻底抛弃MFC, 全面应用Qt 已经不少时间了.除了自己看书按步就班做了 ...

  9. HNCU1741:算法3-2:行编辑程序

    http://hncu.acmclub.com/index.php?app=problem_title&id=111&problem_id=1741 题目描述 一个简单的行编辑程序的功 ...

  10. O2O难解餐饮行业趋势下行之困

    近几年,O2O这个名词越来越常见,我们不但能够在IT相关资讯栏目看到它的存在,甚至在一些综合新闻版面也能轻易看到. 诚然.线下商家结合线上引流这样的方法,能够带来不少订单,可是O2O是否就能够解决餐饮 ...