会话跟踪session

时间:2023-03-09 06:47:34
会话跟踪session

会话跟踪
HTTP是“无状态”协议:客户程序每次读取Web页面,都打开到web服务器的单独的连接,而且,服务器也不自动维护客户的上下文信息。类似客户决定结账时,如何确定之前创建的购物车中哪个属于此客户呢?这种问题有三种解决方案:
cookie、URL重写和隐藏的表单域
cookie处理:
cookie存储购物会话的ID;在后续;连接中,取出当前的会话ID,并使用这个ID从服务器的查找表上提取会话的相关信息。用到两个表:将会话ID与用户关联起来的表和存储用户具体数据的表。
String sessionID = makeUniqueString();
HashMap sessionInfo = new HashMap();
HashMap globalTable = findTableStoringSessions();
globalTable.put(sessionID, sessionInfo);
Cookie sessionCookie = new Cookie("JSESSION", sessionID);
sessionCookie.setPath("/");
response.addCookie(sessionCookie);
这种方式使用cookie是一种绝佳的解决方案,是处理会话常用的方式

url重写:
采用这种方式,客户程序在每个URL尾部加上一些额外数据。这些数据标识当前的会话,服务器将这个标识与它存储的用户相关数据关联起来
隐藏的表单域:
主要缺点是:仅当每个页面都是由表单提交而动态生成才能适用这种方法。

servlet中的会话跟这陪你过
servlet提供一种出色的会话跟踪解决方案:HttpSession API.这个高层接口构筑在cookie和url重写之上
会话跟踪基础:
1、访问与当前请求关联的会话对象
request.getSession获取HttpSession对象。是一个简单的散列表
2、查找与会话相关联的信息
HttpSession的getAttribute
3、存储会话中的信息
setAttribute
4、废弃会话数据
removeAttribute废弃指定的值。invalidate废弃整个会话。logout使客户推出web服务器并作废与用户相关联的所有会话

浏览器会话与服务器会话:
默认,会话跟踪基于存储在浏览器内存中的cookie。

URL重写的话对发往客户的url进行编码:
第一种情况是servlet生成的web页面中含有嵌入的URL。在这种情况下,应该将URL传递给HttpResponse的encodeURL方法。这个方法确定当前是否在使用URL重写,仅在必需时附加会话信息;否则,不做任何更改直接返回传入的URL:
String originalURL = someRelativeOrAbsoluteURL;
String encodeURL = response.encodeURL(originalURL);
out.println("a href=\"" + encodeURL + "\">...</A>")
第二种情况是在sendRedirect调用。这种情况下由于要根据不同的规则确定是否附加会话信息,因此不能使用encodeURL。幸运的是,HttpServletResponse提供encodeRedirectURL方法来处理这种情况:
String originURL = someURL;
String encodedURL = response.encodeRedirectURL(originalURL);
response.sendRedirect(encodedURL);

session:实现购物车的例子:

package com.zhen.test.o5;

import com.zhen.domain.Catalog;
import com.zhen.domain.CatalogItem;
import com.zhen.util.ServletUtilities; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter; /**
* Created by zhen on 2017-11-15.
*/
public class CatalogPage extends HttpServlet {
private CatalogItem[] items;
private String[] itemIDs;
private String title; protected void setItems(String[] itemIDs) {
this.itemIDs = itemIDs;
items = new CatalogItem[itemIDs.length];
for(int i=0; i<items.length; i++){
items[i] = Catalog.getItem(itemIDs[i]);
}
} protected void setTitle(String title) {
this.title = title;
} @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
if(items == null){
resp.sendError(HttpServletResponse.SC_NOT_FOUND, "Missing Items.");
return;
}
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
out.println(ServletUtilities.headWithTitle(title) + "" +
"<body bgcolor=\"#fdf5e6\">" + title + "</h1>");
CatalogItem item;
for(int i=0; i<items.length; i++){
out.println("<hr>");
item = items[i];
if(item == null){
out.println("<font color=\"red\">Unknow item ID " + itemIDs[i] + "</font>");
}else{
out.println();
String formURL = "com.zhen.test.o5.OrderPage";
formURL = resp.encodeURL(formURL);
out.println("<form action=\"" + formURL + "\">" +
"<input type=\"hidden\" name=\"itemID\" value=\"" +item.getItemID()+ "\">\n" +
"<h2>" + item.getShortDescription() + " ($" + item.getCost() + ")</h2>\n" +
item.getLongDescription() + "\n" +
"<br>" +
"<input type=\"submit\" value=\"Add to Shopping Cart\">\n" +
"</form>");
}
}
out.println("</body></html>");
}
} package com.zhen.test.o5; import com.zhen.test.o5.CatalogPage; /**
* Created by zhen on 2017-11-15.
*/
public class KidsBooksPage extends CatalogPage{
public void init(){
String[] ids = {"lewis001", "alexander001", "rowling001"};
setItems(ids);
setTitle("All-Time Best Children's Fantasy Books");
}
} package com.zhen.test.o5; import com.zhen.domain.ItemOrder;
import com.zhen.domain.ShoppingCart;
import com.zhen.util.ServletUtilities; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.NumberFormat;
import java.util.List; /**
* Created by zhen on 2017-11-15.
*/
public class OrderPage extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
ShoppingCart cart;
synchronized (session) {
cart = (ShoppingCart) session.getAttribute("shoppingCart");
if(cart == null){
cart = new ShoppingCart();
session.setAttribute("shoppingCart", cart);
}
String itemID = req.getParameter("itemID");
if(itemID != null){
String numItemString = req.getParameter("numItems");
if(numItemString == null){
cart.addItem(itemID);
}else{
int numItems;
try{
numItems = Integer.parseInt(numItemString);
}catch (NumberFormatException nef){
numItems = 1;
}
cart.setNumOrdered(itemID, numItems);
}
}
}
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
String title = "Status of your Order";
out.println(ServletUtilities.headWithTitle(title) + "" +
"<body bgcolor=\"#fdf5e6\">\n" +
"<h1 align=\"center\">" + title + "</h1>");
synchronized (session){
List itemsOrdered = cart.getItemsOrdered();
if(itemsOrdered.size() == 0){
out.println("<h2><I>No items in your cart...</I></h2");
}else{
out.println("<table border=1 align=\"center\">" +
"<tr bgcolor=\"#ffad00\">" +
" <th>Item ID</th>" +
" <th>Description</th>" +
" <th>Unit Cost</th>" +
" <th>Number</th>" +
" <th>Total Cost</th>" +
"</tr>");
ItemOrder order;
NumberFormat format = NumberFormat.getCurrencyInstance();
for(int i=0; i<itemsOrdered.size(); i++){
order = (ItemOrder) itemsOrdered.get(i);
out.println("<tr>" +
" <td>" + order.getItemID() + "</td>" +
" <td>" + order.getShortItemDescription() + "</td>" +
" <td>" + format.format(order.getUnitCost()) + "</td>" +
" <td>" +
"<form>" +
" <input type=\"hidden\" name=\"itemID\" value=\"" + order.getItemID() + "\"/>\n" +
" <input type=\"text\" name=\"numItems\" size=3 value=\"" + order.getNumItems() + "\"/>\n" +
" <small><input type=\"submit\" value=\"Update Order\"/></small>" +
"</form>" +
" </td>" +
" <td>" + format.format(order.getTotalCost()) + "</td>" +
"</tr>");
}
String checkoutURL = resp.encodeURL("/webApp1/html/Checkout.html");
out.println("</table>" +
"<form action=\"" + checkoutURL + "\">" +
"<big><center>" +
"<input type=\"submit\" value=\"Proceed to Checkout\">" +
"</center></big></form>");
}
out.println("</body></html>");
}
}
} package com.zhen.test.o5; /**
* Created by zhen on 2017-11-15.
*/
public class TeachBooksPage extends CatalogPage {
public void init() {
String[] ids = {"hall001", "hall002"};
setItems(ids);
setTitle("All-Time Best Computer Books");
}
} package com.zhen.domain; /**
* @author zhen
* Created by zhen on 2017-10-30.
*/
public class BidInfo {
private String itemID = "";
private String itemName = "";
private String bidderName = "";
private String emailAddress = "";
private double bidPrice = 0;
private boolean autoIncrement = false; public String getItemID() {
return itemID;
} public void setItemID(String itemID) {
this.itemID = itemID;
} public String getItemName() {
return itemName;
} public void setItemName(String itemName) {
this.itemName = itemName;
} public String getBidderName() {
return bidderName;
} public void setBidderName(String bidderName) {
this.bidderName = bidderName;
} public String getEmailAddress() {
return emailAddress;
} public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
} public double getBidPrice() {
return bidPrice;
} public void setBidPrice(double bidPrice) {
this.bidPrice = bidPrice;
} public boolean isAutoIncrement() {
return autoIncrement;
} public void setAutoIncrement(boolean autoIncrement) {
this.autoIncrement = autoIncrement;
} public boolean isComplete() {
return hasValue(getItemID()) &&
hasValue(getItemName()) &&
hasValue(getBidderName()) &&
hasValue(getEmailAddress()) &&
(getBidPrice() > 0);
} public boolean isPartlyComplete(){
boolean flag = (hasValue(getItemID())) ||
hasValue(getItemName()) ||
hasValue(getBidderName()) ||
hasValue(getEmailAddress()) ||
(getBidPrice() > 0) ||
isAutoIncrement();
return flag;
} private boolean hasValue(String val) {
return (val != null) && (!val.equals(""));
} } package com.zhen.domain; /**
* Created by zhen on 2017-11-15.
*/
public class Catalog {
private static CatalogItem[] items = {
new CatalogItem("hall001",
"<I>Core servlets and JavaServer Pages 2nd Edition<I>",
"by Marty Hall and Larry Brown", 39.95),
new CatalogItem("hall002",
"<I>Core web programming , 2nd Edition<I>",
"by Marty Hall and Larry Brown",
49.99),
new CatalogItem("lewis001",
"<I>The Chronicles of Narina<I>",
"ny C.S Lewis",
19.95),
new CatalogItem("alexander001",
"<I>The Prydain Series<I>",
"by Lloyed Alexander",19.95),
new CatalogItem("rowling001",
"The Harry Potter Series",
"by J.K. Rowling",59.95)
}; public static CatalogItem getItem(String itemID){
CatalogItem item;
if(itemID == null){
return null;
}
for(int i=0; i<items.length; i++){
item = items[i];
if(itemID.equals(item.getItemID())){
return item;
}
}
return null;
}
} package com.zhen.domain; /**
* Created by zhen on 2017-11-15.
*/
public class CatalogItem {
private String itemID;
private String shortDescription;
private String longDescription;
private double cost; public String getItemID() {
return itemID;
} public void setItemID(String itemID) {
this.itemID = itemID;
} public String getShortDescription() {
return shortDescription;
} public void setShortDescription(String shortDescription) {
this.shortDescription = shortDescription;
} public String getLongDescription() {
return longDescription;
} public void setLongDescription(String longDescription) {
this.longDescription = longDescription;
} public double getCost() {
return cost;
} public void setCost(double cost) {
this.cost = cost;
} public CatalogItem(String itemID, String shortDescription, String longDescription, double cost) {
this.itemID = itemID;
this.shortDescription = shortDescription;
this.longDescription = longDescription;
this.cost = cost;
}
} package com.zhen.domain; /**
* Created by zhen on 2017-11-15.
*/
public class ItemOrder {
private CatalogItem item;
private int numItems; public CatalogItem getItem() {
return item;
} public void setItem(CatalogItem item) {
this.item = item;
} public int getNumItems() {
return numItems;
} public void setNumItems(int numItems) {
this.numItems = numItems;
} public ItemOrder(CatalogItem item, int numItems) {
this.item = item;
this.numItems = numItems;
} public ItemOrder(CatalogItem item) {
this.item = item;
this.numItems = 1;
} public String getItemID(){
return getItem().getItemID();
} public String getShortItemDescription(){
return getItem().getShortDescription();
} public String getLongItemDescription(){
return getItem().getLongDescription();
} public double getUnitCost(){
return getItem().getCost();
} public void incrementNumItems(){
setNumItems(getNumItems() + 1);
} public void cancelOrder(){
setNumItems(0);
} public double getTotalCost() {
return getNumItems() * getUnitCost();
}
} package com.zhen.domain; import java.util.ArrayList;
import java.util.List; /**
* Created by zhen on 2017-11-15.
*/
public class ShoppingCart {
private ArrayList itemsOrdered; public ShoppingCart(){
itemsOrdered = new ArrayList();
} public List getItemsOrdered(){
return itemsOrdered;
} public synchronized void addItem(String itemID) {
ItemOrder order;
for(int i=0; i<itemsOrdered.size(); i++){
order = (ItemOrder) itemsOrdered.get(i);
if(order.getItemID().equals(itemID)){
order.incrementNumItems();
return;
}
}
ItemOrder newOrder = new ItemOrder(Catalog.getItem(itemID));
itemsOrdered.add(newOrder);
} public synchronized void setNumOrdered(String itemID, int numOrdered) {
ItemOrder order;
for(int i=0; i<itemsOrdered.size(); i++){
order = (ItemOrder) itemsOrdered.get(i);
if(order.getItemID().equals(itemID)){
if(numOrdered <= 0){
itemsOrdered.remove(i);
}else{
order.setNumItems(numOrdered);
}
return;
}
}
ItemOrder newOrder = new ItemOrder(Catalog.getItem(itemID));
itemsOrdered.add(newOrder);
}
} <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Checking Out</title>
</head>
<body bgcolor="#FDF5E6">
<h1 align="center">Checking Out</h1>
We are sorry, but our electronic credit-card-processing system is currently out of order. Please send a check to:
<pre>
Marty Hall
coreservlets.com, Inc.
6 Meadowsweet Ct., Suite B1
Reisterstown, MD 21136-6020
410-429-5535
hall@coreservlets.com
</pre>
Since we have not yet calculated shipping charges, please sign the check but not fill in the amount. We will generously do that for you.
</body>
</html>