会话管理(二)---Session技术及其使用

Session概述

在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下)。因此,在需要保存用户数据时,服务器程序可以把用户数据写到用户浏览器独占的session中,当用户使用浏览器访问其它程序时,其它程序可以从用户的session中取出该用户的数据,为用户服务。
session是一个域对象,作用范围为整个会话。
Session和Cookie的主要区别在于:
Cookie是把用户的数据写给用户的浏览器。
Session技术把用户的数据写到用户独占的session中。

Session 是一个域
作用范围:当前会话范围
生命周期:
当程序第一次调用到request.getSession()方法时说明客户端明确的需要用到session此时创建出对应客户端的Session对象.
当session超过30分钟(这个时间是可以在web.xml文件中进行修改的)没有人使用则认为session超时销毁这个session.
修改时间:在web.xml文件中<web-app>标签里添加:

<session-config>
    <session-timeout>30</session-timeout> 以分钟为单位的值
</session-config>

程序中明确的调用session.invalidate()方法可以立即杀死session.
当服务器被非正常关闭时,随着虚拟机的死亡而死亡.
如果服务器是正常关闭,还未超时的session会被以文件的形式保存在服务器的work目录下,这个过程叫做session的钝化(Sessions.ser).下次再正常启动服务器时,钝化着的session会被恢复到内存中,这个过程叫做session的活化.
作用:在会话范围内共享数据。

Session原理

request.getSession()方法会检查请求中有没有JSESSIONID cookie,如果有拿出他的值找到对应的session为他服务。
如果没有则检查请求的URL后有没有以参数的形式带着JSESSIONID过来,如果有则找到对应的Session为浏览器服务。
如果还找不到则认为这个浏览器没有对应的Session,创建一个Session然后再在响应中添加JSESSIONID cookie,值就是这个Session 的id。

默认情况下,JSESSIONID 的path为当前web应用的名称,并且没有设置过MaxAge,是一个会话级别的cookie。

这意味着一旦关闭浏览器再新开浏览器时,由于JSESSIONID丢失,会找不到之前的Session。
我们可以手动的发送JSESSIONID cookie,名字和path设置的和自动发送时一样,但是设置一下MaxAge,使浏览器除了在内存中保存JSESSIONID信息以外还在临时文件夹中以文件的形式保存,这样即使重开浏览器仍然可以使用之前的session。

session原理图

URL重写

如果浏览器禁用了Cookie,浏览器就没有办法JSESSIONID cookie,这样就用不了Session了.
我们可以使用URL重写的机制,在所有的超链接后都以参数的形式拼接JSESSIONID信息,从而在点击超链接时可以使用URL参数的方式带回JSESSIONID,从而使用Session
将URL进行重写拼接上JSESSIONID的过程就叫做URL重写

request.getSession() –在URL重写之前一定要先创建出Session,才能进行重写
response.encodeURL()— 一般的地址都用这个方法重写
response.encodeRedirectURL() — 如果地址是用来进行重定向的则使用这个方法

url重写的方法一旦发现浏览器带回了任意cookie信息,则认为客户端没有禁用cookie,就不会再进行重写操作

Session实例

利用session模拟简单的网站购物功能

购物图片

新建prodList.jsp文件,用来显示商品。代码如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" session="false"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  </head>

  <body>
    <%
        request.getSession();

        String url1 = request.getContextPath() + "/servlet/BuyServlet?prod=电视机";
        String url2 = request.getContextPath() + "/servlet/BuyServlet?prod=冰箱";
        String url3 = request.getContextPath() + "/servlet/PayServlet";

        url1 = response.encodeURL(url1);
        url2 = response.encodeURL(url2);
        url3 = response.encodeURL(url3);
    %>

    <a href="<%=url1 %>">电视机</a>
    <a href="<%=url2 %>">冰箱</a>
    <a href="<%=url3 %>">结账</a>
  </body>
</html>

BuyServlet,处理购买商品的逻辑:

package me.zipstream.session;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class BuyServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String prod = request.getParameter("prod");
        prod = new String(prod.getBytes("iso8859-1"), "utf-8");

        HttpSession session = request.getSession();
        Cookie jc = new Cookie("JSESSIONID", session.getId());
        jc.setPath(request.getContextPath());
        jc.setMaxAge(1800);//30minutes
        response.addCookie(jc);

        session.setAttribute("prod", prod);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

PayServlet,显示购买后的逻辑:

package me.zipstream.session;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class PayServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        HttpSession session = request.getSession();

        String prod = (String) session.getAttribute("prod");
        response.getWriter().write("您购买的商品是:" + prod + ",售价5999元。");
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

利用Session实现网站登录的案例

登录注销

新建index.jsp,模拟网站的首页:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  </head>

  <body>
    <h1>我的网站</h1><hr>
    <% 
        //获取Session中的登录状态
        String user = (String) session.getAttribute("user");
    %>

    <% 
        if (user==null || "".equals(user)){
    %>
            欢迎光临!游客!
            <a href="${pageContext.request.contextPath }/loginout/login.jsp">登录</a>
            <a href="#">注册</a>
    <% 
        } else{
    %>
            欢迎回来!<%=user %>
            <a href="${pageContext.request.contextPath }/servlet/LogoutServlet">注销</a>
    <% 
        }
    %>
  </body>
</html>

新建login.jsp,模拟登录页面:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  </head>

  <body>
    <h1>我的网站</h1><hr>
    <form action="${pageContext.request.contextPath }/servlet/LoginServlet" method="POST">
        用户名:<input type="text" name="username" />
        密码:<input type="password" name="password" />
        <input type="submit" value="登录" />
    </form>
  </body>
</html>

新建UserDao类,模拟用户数据库:

package me.zipstream.session.loginout;

import java.util.HashMap;
import java.util.Map;

public class UserDao {

    private UserDao(){}

    private static Map<String, String> map = new HashMap<String, String>();

    static{
        map.put("张三丰", "111");
        map.put("张翠山", "222");
        map.put("张无忌", "333");
    }

    public static boolean valiNamePsw(String username, String password){
        return map.containsKey(username) && map.get(username).equals(password);
    }
}

新建LoginServlet,处理用户登录逻辑:

package me.zipstream.session.loginout;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");

        //获取用户名和密码
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        //查询数据库检查用户名和密码
        if (UserDao.valiNamePsw(username, password)){
            //如果正确登录,则重定向到主页
            request.getSession().setAttribute("user", username);
            response.sendRedirect(request.getContextPath() + "/loginout/index.jsp");
            return;
        } else{
            //如果错误,则提示
            response.getWriter().write("用户名或密码不正确!");
        }
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

新建LogoutServlet,实现用户注销的逻辑:

package me.zipstream.session.loginout;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LogoutServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //杀掉session
        if (request.getSession(false)!=null 
                && request.getSession().getAttribute("user")!=null){
            request.getSession().invalidate();
        }

        //重定向到主页
        response.sendRedirect(request.getContextPath() + "/loginout/index.jsp");
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值