Servlet会话管理三(HttpSession)
Session是服务器端技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的HttpSession对象。由于Session为浏览器用户所独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的Session对象中,当用户再次访问服务器中的其他web资源时,其他web资源再从Session对象中取出用户的数据。
Session和Cookie的最大区别是:
(1)Session是将数据保存在服务器上;而Cookie是将数据以文本的形式保存在客户端浏览器上,由浏览器进行管理的维护。
(2)Session对象可以存放多个name和多个Object;而一个cookie只能放一个name和一个value
HttpSession对象在用户第一次访问网站的时候自动被创建,可以通过调用HttpServletRequest的getSession()方法获取该对象。
HttpSession getSession() // 返回当前Session对象,如果没有则创建一个并返回。
HttpSession getSession(boolean create) // 返回当前Session对象,如果没有,当create是true时创建一个并返回,当create时false时返回null
注意,所有保存在HttpSession对象中的数据不会被发送到客户端,不同于其他会话管理技术,Servlet容器为每个HttpSession生成唯一的标识,并将该标识发送给浏览器,或创建一个名为JSESSIONID的cookie,或在URL后附加一个名为jsessionid的参数。在后续的请求中,浏览器回京标识交给服务器,这样服务器就可以识别请求是由哪个用户发起的。Servlet容器会自动选择一种方式来传递标识,无需开发人员介入。
通过HttpSession的setAttribute(name, value)方法将数据放入Session对象中。可存放多对数据。调用该方法时如果name已经使用过,则新值会覆盖旧值。注意不同于URL重写、表单隐藏域、Cookie技术,放入Session对象中的数据是存储在服务器内存中,因此尽量不要存放太多数据,否则会影响性能。存放在Session对象中的值可以是任意实现了java.io.Serializable接口的java对象,因为Servlet容器必要时会将这些对象放入文件或数据库中。如果对象未实现java.io.Serializable接口,则Servlet容器在序列化的时候会失败并报错。
void setAttribute(java.lang.String name, java.lang.Object value)
通过调用HttpSession的getAttribute(name)方法可以获取之前放入的数据。
java.lang.Object getAttribute(java.lang.String name) // 返回该Session对象中特定名称的数据
java.util.Enumeration<java.lang.String> getAttributeNames() // 返回放入该session对象中的所有数据的名字
可以通过HttpSession的getId()来获取该Session对象的标识
java.lang.String getId() // 获取该Session对象的标识
Seesion的使用原理
1)浏览器第一次访问服务器,服务器会自动创建Session对象,给Session对象分配一个唯一的ID,JSESSIONID
2)将JSESSIONID作为cookie的值发送给浏览器保存
3)浏览器第二次访问服务器时,会将保存有JSESSIONID的cookie随HTTP header发送到服务器
4)服务器从cookie中得到JSESSIONID,然后在服务器中搜索该JSESSIONID的Session对象。找到则直接返回该对象;找不到则创建新的Session对象。
Session对象的销毁
1)调用void invalidate()方法 // 强制该Session对象过期,并清空存储的数据
2)session对象过期(超时)Tomcat 中 session 的默认有效时间是 30 min
3)服务器重启 修改修改 session 持久化配置
修改session默认有效时间
Tomcat中session的默认有效时间是30min。可以在Tomcat安装目录下的 conf/web.xml 文件中修改。
session持久化
session持久化是指当Tomcat重启后,session中仍然含有数据。
可以在 Tomcat 的安装目录下的 conf/context.xml 进行修改
<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!--
<Manager pathname="" />
-->
改为
<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<Manager pathname="" />
实例
package app02a.httpsession; public class Product {
private int id;
private String name;
private String description;
private float price; public Product(int id, String name, String description, float price) {
this.id = id;
this.name = name;
this.description = description;
this.price = price;
} public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
}
package app02a.httpsession; public class ShoppingItem {
private Product product;
private int quantity; public ShoppingItem(Product product, int quantity) {
this.product = product;
this.quantity = quantity;
} public Product getProduct() {
return this.product;
}
public void setProduct(Product product) {
this.product = product;
}
public int getQuantity() {
return this.quantity;
}
public void setQuantiry(int quantity) {
this.quantity = quantity;
}
}
package app02a.httpsession; import java.io.IOException;
import java.io.PrintWriter;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; @WebServlet(name = "ShoppingCartServlet", urlPatterns = { "/products", "/viewProductDetails", "/addToCart", "/viewCart" })
public class ShoppingCartServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private static final String CART_ATTRIBUTE = "cart"; private List<Product> products = new ArrayList<Product>();
private NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(Locale.US); public ShoppingCartServlet() {
super();
} @Override
public void init() throws ServletException {
products.add(new Product(1, "Bravo 32' HDTV", "Low-cost HDTV from renowned TV manufacturer", 159.95F));
products.add(new Product(2, "Bravo BluRay Player", "High quality stylish BluRay palyer", 99.95F));
products.add(new Product(3, "Bravo Stereo system", "5 speaker hifi system with ipod player", 129.95F));
products.add(new Product(4, "Bravo ipod player", "An iPod plug-in that can play multiple formats", 39.95F));
} private void sendProductList(HttpServletResponse response) throws IOException {
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
writer.println("<html>");
writer.println("<head>");
writer.println("<title>Products</title>");
writer.println("<body>");
writer.println("<h2>Products</h2>");
writer.println("<ul>");
for (Product product : products) {
writer.println("<li>" + product.getName() + " (" + currencyFormat.format(product.getPrice()) + ") (" + "<a href='viewProductDetails?id="+ product.getId() + "'>Details)</a></li>");
}
writer.println("</ul>");
writer.println("<a href='viewCart'>View Cart</a>"); // 一个超链接
writer.println("</body>");
writer.println("</html>");
} private Product getProduct(int productId) {
for (Product product : products) {
if (product.getId() == productId) {
return product;
}
}
return null;
} private void sendProductDetails(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
int productId = 0;
try {
productId = Integer.parseInt(request.getParameter("id")); // 获取uri后端的请求字符串
} catch (NumberFormatException e) {
e.printStackTrace();
}
Product product = getProduct(productId);
if (product != null) {
writer.println("<html>");
writer.println("<head>");
writer.println("<title>Product Details</title>");
writer.println("<body>");
writer.println("<h2>Product Details</h2>");
writer.println("<form method='post' action='addToCart'>"); // 提交方式为post, 目标地址为addToCart
writer.println("<input type='hidden' name='id' value='" + productId + "' />"); // 表单隐藏域
writer.println("<table>");
writer.println("<tr>");
writer.println("<td>Name:</td>");
writer.println("<td>" + product.getName() + "</td>");
writer.println("</tr>");
writer.println("<tr>");
writer.println("<td>Description:</td>");
writer.println("<td>" + product.getDescription() + "</td>");
writer.println("</tr>");
writer.println("<tr>");
writer.println("<td><input name='quantity' /></td>"); // 默认type="text"
writer.println("<td><input type='submit' value='Buy'></td>"); // 提交按钮
writer.println("</tr>");
writer.println("<tr>");
writer.println("<td colspan='2'><a href='products'>Product List</a></td>"); // 返回到产品列表的超链接
writer.println("</tr>");
writer.println("</table>");
writer.println("</body>");
writer.println("</html>");
} else {
writer.println("No product found");
}
} private void showCart(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html");
PrintWriter writer = response.getWriter();
writer.println("<html>");
writer.println("<head>");
writer.println("<title>Shopping Cart</title>");
writer.println("</head>");
writer.println("<body>");
writer.println("<a href='products'>Product List</a>"); // 返回到产品列表的超链接
HttpSession session = request.getSession(); // 获得当前的HttpSession对象
List<ShoppingItem> cart = (List<ShoppingItem>)session.getAttribute(CART_ATTRIBUTE);
if (cart != null) {
writer.println("<table>");
writer.println("<tr>");
writer.println("<td style='width:150px'>Product</td>"); // 元素内嵌样式
writer.println("<td style='width:150px'>Quantity</td>");
writer.println("<td style='width:150px'>Price</td>");
writer.println("<td style='width:150px'>Amount</td>");
writer.println("<tr>");
double total = 0.0;
for (ShoppingItem shoppingItem : cart) {
Product product = shoppingItem.getProduct();
int quantity = shoppingItem.getQuantity();
if (quantity != 0) {
float price = product.getPrice();
double subtotal = price * quantity;
writer.println("<tr>");
writer.println("<td>" + product.getName() + "</td>");
writer.println("<td>" + quantity + "</td>");
writer.println("<td>" + currencyFormat.format(price) + "</td>");
writer.println("<td>" + currencyFormat.format(subtotal) + "</td>");
total += subtotal;
writer.println("</tr>");
}
}
writer.println("<tr>");
writer.println("<td colspan='3' style='text-align:right'>Total: </td>");
writer.println("<td>" + currencyFormat.format(total) + "</td>");
writer.println("</tr>");
writer.println("</table>");
}
writer.println("</body>");
writer.println("</html>");
} @Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String uri = request.getRequestURI();
if (uri.endsWith("/products")) { // 根据不同的uri调用不同的方法处理
sendProductList(response);
}else if (uri.endsWith("/viewProductDetails")) {
sendProductDetails(request, response);
}else if (uri.endsWith("viewCart")) {
showCart(request, response);
}
} protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int productId = 0;
int quantity = 0;
try {
productId = Integer.parseInt(request.getParameter("id")); // 即可以或的token的值
quantity = Integer.parseInt(request.getParameter("quantity")); // 也可以获的表单隐藏域的值
} catch (NumberFormatException e) {
e.printStackTrace();
}
Product product = getProduct(productId);
if (product != null) {
ShoppingItem shoppingItem = new ShoppingItem(product, quantity);
HttpSession session = request.getSession(); // HttpSession对象被自动创建,该方法可以获得httpSession对象
List<ShoppingItem> cart = (List<ShoppingItem>) session.getAttribute(CART_ATTRIBUTE);
if (cart == null) {
cart = new ArrayList<ShoppingItem>();
session.setAttribute(CART_ATTRIBUTE, cart); // 向HttpSession对象绑定数据
}
cart.add(shoppingItem);
}
sendProductList(response);
}
}
Servlet会话管理三(HttpSession)的更多相关文章
- servlet 会话管理
一.URL 重写 URL 重写是一种会话跟踪技术,它将一个或多个token添加到URL的查询字符串中,每个token通常为 key=value形式,如下: url?key-1=value-1& ...
- Servlet会话管理一(URL重写和表单隐藏域)
会话可以简单的理解为客户端用户打开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器的整个过程称为一个会话.即一个客户端用户和服务器端进行通讯的过程,也是客户端和服务器端之间的数据传 ...
- Java Web(三) Servlet会话管理
会话跟踪 什么是会话? 可简单理解为,用户打开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭服务器,整个过程称为一个会话.从特定客户端到服务器的一系列请求称为会话.记录会话信息的技术称 ...
- Servlet会话管理二(Cookie)
Cookie是在HTTP协议下,将服务器传递给浏览器的的少量信息保存到浏览器客户端的一种技术,通过这种技术,即使在浏览器被关闭或链接中断的情况下,用户仍可以维护Cookie中的数据. Cookie是经 ...
- Java EE.Servlet.会话管理
一次会话是从客户打开浏览器开始到关闭浏览器结束.记录会话信息的技术称为会话跟踪.常见的会话跟踪技术有Cookie.URL重写和隐藏表单域. 1.Cookie Cookie是一小块可以嵌入到HTTP请求 ...
- Servle中的会话管理
最近整理了下会话管理的相关笔记,以下做个总结: 一.会话管理(HttpSession) 1.Web服务器跟踪客户状态的四种方法: 1).使用Servlet API的Session机制(常用) 2).使 ...
- jsp/servlet学习三之会话管理初解
由于http的无状态性,使得会话管理或会话跟踪成为web应用开发一个无可避免的主题.默认下,一个web服务器无法区分一个http请求是否为第一次访问.例如,一个web邮件应用要求用户登陆后才能查看邮件 ...
- [Servlet&JSP] HttpSession会话管理
我们能够将会话期间必须共享的资料保存在HttpSession中,使之成为属性.假设用户关掉浏览器接受Cookie的功能.HttpSession也能够改用URL重写的方式继续其会话管理功能. HttpS ...
- java web Servlet 学习笔记 -3 会话管理技术
Cookie和HttpSession 什么是会话: 用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话. 每个用户在使用浏览器与服务器进行会话的过 ...
随机推荐
- powerdessigner使用教程
https://jingyan.baidu.com/article/86fae346e089393c49121a11.html
- selenium自动化测试之整合测试报告
selenium自动化测试之整合测试报告 标签(空格分隔): 整合报告 如下截图我们添加一个文件叫做:latest_report.py文件, import time import os import ...
- Python之-------基础数据类型
数据类型: 计算可以处理各种不同文件,图形,音频,视频,网页等各种各样的数据,不同的数据,需要定义不同的数据类型.在Python中,能够直接处理的数据类型有以下几种: 一:nubmer(数字) 1.1 ...
- 《深入理解java虚拟机》笔记
二.java内存区域与内存溢出异常 0.在内存管理领域,java与c/c++不同的是,在java虚拟机自动内存管理机制下,java不需要手动去为对象写配对的free内存的代码,不容易出现内存泄漏和内存 ...
- 获取txt里面的内容
import flash.net.URLLoader; import flash.net.URLRequest; import flash.events.Event; var txtLoad:URLL ...
- 牛客网练习赛12---A and B
A题传送门:https://www.nowcoder.net/acm/contest/68/A B题传送门: https://www.nowcoder.net/acm/contest/68/B A ...
- AD操作
加泪滴 批量添加覆铜过孔(先铺铜以后,再批量添加过孔) 开槽 在KEPP—OUT层 部分区域 不敷铜 开窗
- js正则表达式中的正向肯定预查和正向否定预查
对于没有使用过这几个表达式的人,应该对这个概念都有点不太理解,下面就以实际例子说明这几个表达式的用户. 一.?:pattern——匹配检验:会作为匹配校验,是一个非获取匹配,并出现在匹配字符结果里面, ...
- HDU 1542 Atlantis(线段树面积并)
描述 There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. S ...
- day 16 包,random,shutil
包: 函数过多,可以分模块文件去管理函数,模块文件过多,将模块文件分类放在一个个的文件夹中,这个文件夹就叫做包,组织结构更加清晰,合理! 模式就是被别人使用,包既然是一些模块的集合,也是被调用. 文件 ...