为什么要进行会话跟踪
首先用户浏览网页或者其他网页的操作信息是需要被记录已提供更好的服务的,例如购物车的购物清单,用户买多个东西需要多次请求,而这些请求需要被记录来,对用户的逻辑上相关联的多次不同的访问请求进行记录就叫用户跟踪。
http协议是无状态协议,也就是说HTTP协议无法将同一个用户的多个请求关联在一起,每次请求都是独立的。这也就意味着同一个用户的多次访问是无法记忆的,需要借助其他手段。
会话是一与单个客户关联的对象,管理与该用户相关的数据,我们可以创建和销毁会话。这些数据也可以在会话结束是保存在服务器上。
实现跟踪的三种方式:
1.Cookies
2.URL重写
3.隐藏式表单域
1.Cookies
该机制是使用最广泛的跟踪机制。Cookies由服务器提供,并发送给客户端,此文件为保存在本地的文本文件,由客户端填写,客户端在一次会话中的多次请求都可以携带Cookies来进行访问。于此同时,Cookie文件一般不大于4KB,且一个域不多于20个Cookie,敏感信息和隐私信息不应写在Cookies中。Cookies是临时的,可以设置超期时长。
例子:
建立一个文件,让其产生Cookies,即创建一个Cookie对象,然后用response发送给客户端。客户端接收该页面同时接收该Cookies,再次访问其他页面,默认带着该web程序的Cookies。在另一个页面中就可以获取这个Cookie了。
这是创建页面:
<body>
<% Cookie newCookie = new Cookie("userID","125436987");
newCookie.setMaxAge(24*60*60);
response.addCookie(newCookie);
%>
<h1>this is the cookie test</h1>
<a href="getCookie.jsp">to get it</a>
</body>
这是获取页面:getCookie.jsp
<body>
<% Cookie[] a= request.getCookies(); %>
the cookies name is <% out.print(a[0].getName());%> <br/>
the cookies ID is <% out.print(a[0].getValue()); %> <br/>
</body>
2.URL重写:
在URL最后附加标识会话的数据,与标识符关联的服务器会根据这个标识保存或者获取相关数据。这种方法需要在URL中附加信息且隐私问题暴露明显,在用户跟踪上用得少。
3.隐藏式的表单域
表单有类型为hidden的,在提交表单数据时提交,提交的数据会保存在post/get数据中。不过用途有限。
JSP中的Session对象
jsp中的隐藏对象使用的上面三种中的一种,具体细节不对开发者透露。如果可能tomcat用Cookie去识别客户,否则回头用URL重写。
实践
建立如下jsp
<body bgcolor="white">
<%
Integer times = (Integer)session.getAttribute("times");
if(times==null){
times = new Integer(1);
}else{
times = new Integer(times.intValue()+1);
}
session.setAttribute("times", times);
%>
<table border =2 align="center">
<tr bgcolor="#FFE4E1">
<th>name</th>
<th>value</th>
</tr>
<tr bgcolor="C0C0C0">
<td>ID</td>
<td><%=session.getId() %>
</td>
<tr bgcolor="FAFAD2">
<td>CreateTime</td>
<td><%=session.getCreationTime()%></td>
</tr>
<tr bgcolor="C0C0C0">
<td>LastAccessedTime</td>
<td><%=session.getLastAccessedTime() %></td>
</tr>
<tr bgcolor="FAFAD2">
<td>Times</td>
<td><%=times %></td>
</tr>
</table>
</body>
上边代码,每次访问都获取该session的times属性,并加一,由于该session会保存该属性,因此多次访问就会显示访问次数,逻辑很简单,只是演示下session的数据保存和读取。
效果如下:
session范围的javabean
通过一个例子来看在session范围的javabean数据的存取。该例子通过添加按钮发送请求,并set到bean属性里面,再放到bean的list里面,每次请求都会添加数据。
javabean如下:
package javaBeansInJSP;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
public class ShoppingCart {
private String name=null;
private List<String> shoppingCartList=new ArrayList<>();
private String submit=null;
public void setSubmit(String submit) {
this.submit = submit;
}
public String getSubmit() {
return submit;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void addProduct() {
if(name!=null)
shoppingCartList.add(name);
}
public void processReq(HttpServletRequest req) throws UnsupportedEncodingException {
if(req!=null){
addProduct();
}
}
private void removeProduct() {
// TODO Auto-generated method stub
if(shoppingCartList!=null)
shoppingCartList.remove(name);
}
public List<String> getshoppingCart() {
return shoppingCartList;
}
}
建立一个jsp文件,其中setProperty(name=”” property=”*”)就是把request里面的所有属性值,设置到javabean里面的对应属性上。
<%@page import="java.util.Enumeration"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
<form method = post action="shopping.jsp">
<select name = "name">
<option>至高之拳</option>
<option>未来战士</option>
<option>屠龙勇士</option>
<option>圣诞老人</option>
</select>
<input type=submit name="submit" value="添加">
</form>
<hr>
<jsp:useBean id="shoppingCart" class="javaBeansInJSP.ShoppingCart" scope="session"></jsp:useBean>
<jsp:setProperty name="shoppingCart" property="*"/>
<% shoppingCart.processReq(request);
String aaa= shoppingCart.getshoppingCart().get(0);
out.println(new String(aaa.getBytes("iso-8859-1"),"utf-8"));
for(Enumeration e=request.getParameterNames();e.hasMoreElements();){
out.println(new String(request.getParameter((String)e.nextElement()).getBytes("iso-8859-1"),"utf-8"));
}%>
<% if(shoppingCart.getshoppingCart()!=null){
for(String skin : shoppingCart.getshoppingCart()){
//中文需要转码 要不然乱码
String skinCN = new String(skin.getBytes("iso-8859-1"),"utf-8");
%>
<table>
<tr>
<th>已添加商品</th>
</tr>
<tr>
<td><%=skinCN %></td>
</tr>
<%}} %>
</table>
</body>
</html>
可以运行:多次点击添加按钮就会出现: