使用会话维持状态

一、会话

为了实现关联同一个用户端的多个请求和这些请求之间数据的共享,需要用到会话,会话用于维持请求和请求之间的状态。从服务器的角度,当用户的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. java8版本base64加密解密

    首先,先是加密,这里我使用了base64类 try { String asB64 = Base64.getEncoder().encodeToString("http://www.baidu ...

  2. 【NOIP2016提高组】蚯蚓

    https://www.luogu.org/problem/show?pid=2827 首先考虑暴力:每次都是拿最长的蚯蚓,容易想到用堆.每次除拿出来的以外所有的蚯蚓都增长,容易想到用一个懒惰标记来记 ...

  3. centos 6.5 安装mongodb2.6

    前言: 系统版本号:Centos-6.5-x86_64 *** Centos编译安装mongodb 2.6 系统最好是64位的,才干更好发挥mongodb的性能 1.准备,下载源文件(二进制编译版) ...

  4. C++ Primer高速入门之三:几种常见的控制语句

    语句总是顺序运行的:第一条语句运行完了接着是第二条,第三条等等.这是最简单的情况,为了更好的控制语句的运行.程序设计语言提供了多种控制结构支持更为复杂的语句运行.我们就来看看C++ 提供的控制方式. ...

  5. EventBus猜想 ----手把手带你自己实现一个EventBus

    本文是什么 本文是一篇怀着推測角度学习一个未知东西(EventBus)的文章. 先推測EventBus是怎样实现的. 依据推測去模仿他的实现. 查看源代码.验证猜想. 更深入的去理解他. 转载请注明出 ...

  6. webpack+babel+transform-runtime, IE下提示Promise未定义?

    知识要求 babel的基础知识(推荐阮一峰的babel入门教程) 充分理解babel-plugin-transform-runtime与babel-runtime的作用(推荐github项目首页) w ...

  7. Jquery对话框基本配置

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px "PingFang SC" } p.p2 { margin: 0.0px ...

  8. 盘点selenium phantomJS使用的坑

    参考:http://www.jianshu.com/p/9d408e21dc3a   http://www.cnblogs.com/luxiaojun/p/6144748.html 豆瓣应该是ip被封 ...

  9. intellij IDEA里各图标对应的文件类型

    本篇内容为大家提供的是IntelliJ IDEA 使用教程中的常见文件类型的图标介绍,IntelliJ IDEA是java语言开发的集成环境,IntelliJ在业界被公认为最好的java开发工具之一, ...

  10. Kendo UI使用笔记

    1.Grid中的列字段绑定模板字段方法参数传值字符串加双引号: 上图就是个典型的例子,openSendWin方法里Id,EmergencyTitle,EmergencyDetail 三个参数,后两个参 ...