使用会话维持状态

一、会话

为了实现关联同一个用户端的多个请求和这些请求之间数据的共享,需要用到会话,会话用于维持请求和请求之间的状态。从服务器的角度,当用户的Web浏览器打开第一个链接到服务器的套接字时请求就开始了,直到服务器返回最后一个数据包并关闭链接是,该请求将结束。此时用户浏览器和服务器之间不再有任何的联系,当下一个链接开始时,无法将新的请求和之前的请求关联起来。

维持状态

最经典的例子就是在线购物网站需要用购物车来保证用户和商品都能够被保持。

记住用户

这样的例子是用户论坛网站,在多个操作中,用户只需要登录一次。

启动任务程序工作流

用户在使用Web应用程序完成某个任务时,需要某种形式的工作流,比如新闻的发布。

二、使用会话cookie和URL重写。

会话是由服务器或Web应用程序管理的某些文件、内存片段、对象或者容器,它包含了分配给它的各种不同数据。

通常会话被赋予一个随机生成的字符串,称为会话ID。第一次创建会话时,创建的会话ID会作为响应的一部分返回到用户的浏览器中。接下来从该用户浏览器发出的请求都将通过某种方式包含这个会话ID。当应用程序收到含有会话ID的请求时,它可以通过该ID将现有会话和当前请求关联起来。

实现会话ID从服务器返回到浏览器中的方法包括会话cookie和URL重写。

会话cookie

这种技术也叫HTTP cookie。cookie是一种必要的通信机制,可以通过Set-Cookie响应头在服务器和浏览器中传递任意数据,并存储在用户计算机中,然后再通过请求头Cookie从浏览器返回到服务器中。cookie包含了域名、路径、过期日期或最大生命周期,安全标志或只含有HTTP标志。会话cookie的名字默认为JSESSIONID。

Domain将告诉浏览器应该将cookie发送到哪个域名中,

Path则进一步将cookie限制在相对于域的某个特定的URL中,

Expries定义了cookie的绝对过期日期,

如果存在Secure特性,浏览器只会通过HTTPS发送cookie,进行加密传输,

HttpOnly将cookie限制在浏览器,避免JavaScript和flash。

URL中的会话ID

另一种传输会话ID的方式是通过URL,Web服务器直到如何查找URL中包含会话ID的特定模式,不同的技术对如何在URL中内嵌和定位会话ID使用不同的策略。在Java EE中,会话ID被添加到URL的最后一个路径段的举证参数中,通过这种方式会分离开会话ID与查询字符串的参数。例如:

http://www.example.com/supprot;JSESSIONID=NRxclGg2vG7kI4MdlLn?foo=bar

必须将会话ID内嵌在应用程序返回的所有URL中,包括页面的链接、表单操作以及重定向。

HttpServletResponse接口定义了两个重写URL的方法:encodeURL和encodeRedirectURL,它们将在必要的时候把会话ID内嵌在URL中。

漏洞

复制粘贴错误,会话固定,跨站脚本和会话劫持,不安全的cookie

三、在会话中存储数据

在部署描述符中配置会话:

    <session-config>
<session-timeout>30</session-timeout>
<cookie-config>
<http-only>true</http-only>
</cookie-config>
<tracking-mode>COOKIE</tracking-mode>
</session-config>

所有的<session-config>和<cookie-config>标签都是可选的,至于标签的作用可以另行查看。使用上述配置,会话超时时间为30min,只接受cookie用于会话追踪,。

存储,删除和获取数据:

在Servlet中创建map,可以使用该Map来进行数据的相关操作。

private final Map<Integer, String> products = new Hashtable<>();

    public StoreServlet()
{
this.products.put(1, "Sandpaper");
this.products.put(2, "Nails");
this.products.put(3, "Glue");
this.products.put(4, "Paint");
this.products.put(5, "Tape");
}

1.doGet方法中的使用:

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
String action = request.getParameter("action");
if(action == null)
action = "browse"; switch(action)
{
case "addToCart":
this.addToCart(request, response);
break; case "emptyCart":
this.emptyCart(request, response);
break; case "viewCart":
this.viewCart(request, response);
break; case "browse":
default:
this.browse(request, response);
break;
}
} private void addToCart(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
int productId;
try
{
productId = Integer.parseInt(request.getParameter("productId"));
}
catch(Exception e)
{
response.sendRedirect("shop");
return;
} HttpSession session = request.getSession();
if(session.getAttribute("cart") == null)
session.setAttribute("cart", new Hashtable<Integer, Integer>()); @SuppressWarnings("unchecked")
Map<Integer, Integer> cart =
(Map<Integer, Integer>)session.getAttribute("cart");
if(!cart.containsKey(productId))
cart.put(productId, 0);
cart.put(productId, cart.get(productId) + 1); response.sendRedirect("shop?action=viewCart");
} private void emptyCart(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
request.getSession().removeAttribute("cart");
response.sendRedirect("shop?action=viewCart");
} private void viewCart(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
request.setAttribute("products", this.products);
request.getRequestDispatcher("/WEB-INF/jsp/view/viewCart.jsp")
.forward(request, response);
} private void browse(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
request.setAttribute("products", this.products);
request.getRequestDispatcher("/WEB-INF/jsp/view/browse.jsp")
.forward(request, response);
}

四、将使用会话的用户群集化

集群为应用程序增加了冗余和可扩展性,经过正确配置的群集应用程序即使在遇到某些服务器终止时也能够正常运行,是指在执行日常维护工作时也可以正常处理用户请求。管理员甚至可以升级应用程序,并保证应用程序不会终止对请求的处理。

Advanced Message Queuing Protocol(AMQP)、Java Message Service(JMS)、Microsoft Message Queuing(MSMQ)。

问题:会话一对象的方式存在于内存中,并且只存在于Web容器的单个实例中,来自同一个客户端的两个连续请求将会访问不同的Web容器,而第一个容器分配的ID,第二个容器无法识别。

解决:使用粘滞会话:使负载均衡机制能够感知到会话,并且总是将来自于同一会话的请求发送到相同的服务器。(取决于负载均衡技术,比如负载均衡器在响应中添加他们自己的会话cookie,并在后学的请求中识别这些cookie)。

Java Web高级编程(二)的更多相关文章

  1. Java Web高级编程(四)

    WebSocket 一.WebSocket的产生 用户希望Web页面可以进行交互,用于解决这个问题的技术是JavaScript,现在Web上有许多的可用的JavaScript框架,在使用极少的Java ...

  2. Java Web高级编程(三)

    使用过滤器改进应用程序 一.过滤器的目的 过滤器是可以拦截访问资源的请求.资源的响应或者同时拦截两者的应用组件.过滤器可以检测和修改请求和响应,同时也可以拒绝.重定向或转发请求.javax.servl ...

  3. Java Web高级编程(一)

    Servlet 一.创建Servlet类 在Java EE中,Servlet用来接收和响应终端用户的请求.Servlet是所有Web应用程序的核心类,是唯一既可以直接处理和响应用户请求,也可以将处理工 ...

  4. java web高级编程 笔记1

    chapter1:了解web应用程序 web应用程序主要组件: Servlet 过滤器 监听器 JSP chapter2:各类web容器介绍 略 chapter3:Servlet介绍 Servlet是 ...

  5. Java Web高性能开发(二)

    今日要闻: 性价比是个骗局: 对某个产品学上三五天个把月,然后就要花最少的钱买最多最好的东西占最大的便宜. 感谢万能的互联网,他顺利得手,顺便享受了智商上的无上满足以及居高临下的优越感--你们一千块买 ...

  6. C++面向对象高级编程(二)基础篇

    技术在于交流.沟通,转载请注明出处并保持作品的完整性. 概要 知识点1.重载成员函数 知识点2 . return by value, return by reference 知识点3 重载非成员函数 ...

  7. Servlet视频-开发第一个java web(最简单的java web程序)(二)

    web项目有目录结构要求 WEB-INFO 文件夹 是一个Servlet规范,必须要这么命名,在换个文件夹里面如果创建一个jsp文件是不能直接访问的,在WEB-INfO文件夹之外创建的jsp可以直接访 ...

  8. java web学习总结(二十五) -------------------JSP中的九个内置对象

    一.JSP运行原理 每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理.JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet ...

  9. java web学习总结(二十九) -------------------JavaBean的两种开发模式

    SUN公司推出JSP技术后,同时也推荐了两种web应用程序的开发模式,一种是JSP+JavaBean模式,一种是Servlet+JSP+JavaBean模式. 一.JSP+JavaBean开发模式 1 ...

随机推荐

  1. Jsoup(一)Jsoup详解(官方)

    一.Jsoup概述 1.1.简介     jsoup 是一款Java 的HTML解析器,可直接解析某个URL地址.HTML文本内容.它提供了一套非常省力的API, 可通过DOM,CSS以及类似于jQu ...

  2. msf入门学习笔记

    msf-------------------------------------- service postgresql startservice metasploit startmsfconsole ...

  3. 【tyvj P4879】骰子游戏

    http://www.tyvj.cn/p/4879 首先,投一个骰子,每个数字出现的概率都是一样的.也就是不算小A的话,n个人投出x个骰子需要的次数和点数无关. 计数问题考虑dp,令f(i,j)为前i ...

  4. Codeforces 817F MEX Queries

    题意:对一个维护三种操作:1.将[l..r]中的数全部加入集合中.2.将集合中[l..r]范围内的数删去.3.将集合中在[l..r]中的数删去,并将之前不在集合中的数加入集合 考虑到最近线段树总是写爆 ...

  5. CF Round#436 div2

    额,这次的题目其实挺智障的.所以通过这次比赛,我也发现了自己是一个智障.... 不说太多,说多是泪... A. Fair Game 题意:给你一个数组,看你能否把它均分为两个所有元素均相同的子数组. ...

  6. log4j2 项目日志组件

    在项目运行过程中,常常需要进行功能调试以及用户行为的跟踪和记录,部分人习惯使用System.out,但这并不建议,它仅仅是使用方便但不便于维护也无扩展性.相比log4j的话,log4j可以控制日志信息 ...

  7. ZOJ 2859 二维RMQ(模板)

    这题求范围最小值,RMQ正好是用来解决这方面的.所以再适合只是了,又是离线静态输入输出的,所以时间比二维线段树快. #include<iostream> #include<cstdi ...

  8. mac os x 触摸板点击无效

    macbook默认轻击触摸板无效,这样是为了防止误点击.可是习惯了windows笔记本的我对这一设置非常不习惯. 能够在"system preference"的"Trac ...

  9. Linux多线程实践(三)线程的基本属性设置API

    POSIX 线程库定义了线程属性对象 pthread_attr_t ,它封装了线程的创建者能够訪问和改动的线程属性.主要包含例如以下属性: 1. 作用域(scope) 2. 栈尺寸(stack siz ...

  10. python抓取历年特码开奖记录

    背景: 小时候,有种游戏,两个主人公:白XX和曾XX,每个家庭把他俩像活菩萨一样供着,供他们吃,供他们穿 做生意的老板为了这两位活菩萨,关门大吉 农民为了这两位活菩萨卖牛卖田变卖家产 做官的为了这两位 ...