Session的出现弥补了Cookie的谋陷安全性的不足。
Session是将数据缓存在服务器端。
Session的生命周期:
创建:在访问Servlet时第一次遇到getSession();
销毁:当回话结束,30分钟内没有对其进行访问。
Session的作用机理:
一个回话对Servlet进行访问,且getSession()时,服务器就会创建一个Session,这个Session有自己的ID。并且 服务器会把SessionID以Cookie形式回写给浏览器。浏览器访问 服务器的其他web资源时就会带着Cookie(maxAge为默认值,关掉浏览器清除)去,服务器会根据客户机带来的SessionID寻找相应的Session,而不去创建新的了。
但是,我们有这样的需求:
允许用户的不小心操作,比如:用户买了100本书,但是没有进行结账,他不小心关掉了浏览器(回话结束)。我们想如何保存他买的书,让他不需要重新去购买了。
我们就需要不让那个Cookie在浏览器关闭后进行清除。
我们重写 名为JSESSION的Cookie
// 获取session
HttpSession sessoin = request.getSession();
// 重写保存sessionID的cookie,并重新设置他的时间
String sessionID = sessoin.getId();
//这个cookie的名字就是叫JSESSION
Cookie cookie = new Cookie("JSESSIONID", sessionID);
// 回话结束后,三十分钟没有人使用session,session就摧毁,cookie就没有必要继续保存了
cookie.setMaxAge(30 * 60);
//你的工程目录
cookie.setPath("/Day07");
response.addCookie(cookie);
做商务网站还会出现另一种问题:
用户不小心“禁用cookie”了,我们session的工作就不能正常进行了。因为,用户访问时不会带来sessionID了,我们总是会为他创建新的session,这样,他购买的东西,就不会被结账servlet所得到。
(注意做实验时,一定要把cookie禁掉,并要把cookie清空一下)
我们就需要一种名为URL重写的技术。
这就牵扯到session的深层工作原理了:getSession()时,首先会判断你是不是带着有sessionID的cookie来的,不是的话就判断你的URL上是不是带了sessionID。两者都不是时,服务器才会为用户创建session。
(因为还没开始学jsp,先使用servlet来代替)
// 创建session,只要创建了就好
request.getSession();
//使用response的encodeURL()方法来重写URL,加上SessionID标志
String u1 = response.encodeURL("/Day07/servlet/SessionDemo1");
String u2 = response.encodeURL("/Day07/servlet/SessionDemo2");
out.print("购买
");
out.print("结账");
这样就算用户不小心禁用了Cookie,我们同样可以获取到用户所买的东西。
Session的小案例:(使用session技术实现的小购物车)
//首页显示所有的book,点击<购买>超链接后,到BuyServlet
public class BookMarket extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 设置编码
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
// 显示出所有的书
Map map = DB.getAll();
for (Map.Entry entry : map.entrySet()) {
out.print(entry.getValue().getName() + "--" + "购买
");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
/**
* 模拟数据库
* @author majin
*/
class DB {
private static LinkedHashMap books = new LinkedHashMap();
static {
books.put("1", new Book("1", "海贼王", "尾田荣一郎", "一本绝世佳书"));
books.put("2", new Book("2", "死神", "久保带人", "一本好漫画"));
books.put("3", new Book("3", "火影忍者", "忘了", "一本好漫画"));
books.put("4", new Book("4", "嗜血狂袭", "不知道", "一本黄色漫画"));
}
public static LinkedHashMap getAll() {
return books;
}
}
//封装一本书的详细信息
class Book implements Serializable{
private String id = null;
private String name = null;
private String author = null;
private String description = null;
//constructor
//getter and settter
}
//购买,把当前的书加入到购物车。然后跳转到购物车
public class BuyServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//编码
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
//拿到当前要购买的书
String id = request.getParameter("id");
Book book = DB.getAll().get(id);
//得到用户的 购书集合,第一次进行创建,把当前要购买的书加入到集合中
HttpSession session = request.getSession();
List list = (List) session.getAttribute("list");
if(list == null){
list =new ArrayList();
session.setAttribute("list", list);
}
list.add(book);
//先试试转发?
//request.getRequestDispatcher("/servlet/PayServlet").forward(request, response);
//实现跳转
response.sendRedirect("/Day07/servlet/PayServlet");
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
//购物车界面,显示用户买了那些书
public class PayServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//编码
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.print("您购买了:
");
HttpSession session = request.getSession();
List list = (List) session.getAttribute("list");
for (Book book : list) {
out.print(book.getName()+"
");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}