Session

# 客户跟踪
实现客户端跟踪有4种常见的方法:隐藏域、URL重写、客户端跟踪cookie、服务器跟踪session

## Session
session用于绑定用户在当前应用种实现跨页面数据传递

HttpSession是Java平台对session机制的实现规范,因为它仅仅是个接口,具体到每个web应用服务器的提供商,除了对规范支持之外,仍然会有一些规范里没有规定的细微差异

HttpSession类它提供了setAttribute()和getAttribute()方法存储和检索对象,提供了一个会话ID关键字,一个参与会话行为的客户端在同一会话的请求中存储和返回它。servlet引擎查找适当的会话对象,并使之对当前请求可用。HttpServletRequest 接口提供了方法来获取HttpSession实例。
HttpSession session=request.getSession();
HttpServletRequest对象提供的方法:
- public HttpSession getSession() :该方法取得请求所在的会话。相当于request.getSession(true)
- public HttpSession getSession(Boolean create):返回当前请求的会话。如果当前请求不属于任何会话,而且create参数为true,则创建一个会话,否则false表示返回null。此后所有来自同一个的请求都属于这个会话,通过它的getSession返回的是当前会话

使用session传递数据的方法

- public void setAttribute(String name,Object value) 将value对象以name名称绑定到会话
- public object getAttribute(String name) 取得name的属性值,如果属性不存在则返回null
- public void removeAttribute(String name) 从会话中删除name属性,如果不存在不会执行,也不会抛出错误
- public Enumeration getAttributeNames() 返回和会话有关的枚举值

典型应用:

利用session将验证码从PicServlet传递到LoginServlet中

生成验证码的PicServlet
String checkcode=this.getCheckCode(6);
HttpSession session=request.getSession();
session.setAttribute("checkcode",checkcode);

登录处理LoginServlet
//接收提交数据
String checkCode=request.getParameter("checkcode");
Object obj=session.getAttribute("checkcode");
if(checkCode!=null && checkCode.length()>0){
    if(checkCode.equals(obj))  验证通过
    else 验证失败!
}

验证通过后使用session存储登录成功标识
boolean bb=userDao.login(user);
if(bb){
    HttpSession session=request.getSession();
    session.setAttribute("loginInto",user);
}    

-public void invalidate() 使会话失效,同时删除属性对象

登录成功后的退出登录
public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{
    HttpSession session=request.getSession();
    session.invalidate();
    response.sendRedirect("login.do");
}

直接关闭页面退出当前应用

session可以设置超时时长,当不使用session对象超过超时配置时,会由服务器自动执行销毁操作。tomcat默认超时时长为30分钟。配置位于web.xml
<session-config>
    <session-timeout>30</session-timeout>
</session-config>

- 如果期望应用具有高安全性,则减少超时时间,例如20分钟
- 如果期望应用对客户更友好一些,则加长超时时间设置,例如40分钟

其它方法

- public Boolean isNew() 用于检测当前客户是否为新的会话
- public long getCreationTime() 返回会话创建时间
- public long getLastAccessedTime() 返回在会话时间内web容器接收到客户最后发出的请求的时间
- public int getMaxInactiveInterval() 返回在会话期间内客户请求的最长时间为秒
- public void setMaxInactiveInterval(int seconds) 允许客户客户请求的最长时间
- ServletContext getServletContext() 返回当前会话的上下文环境,ServletContext对象可以使Servlet与web容器进行通信
- public String getId() 返回会话期间的识别号

### session的实现原理

session依赖Cookie。

- 当客户端第一次访问服务器时,服务器会为客户端创建一个session对象,然后把session对象放到session池中,在响应时把sessionId通过Cookie响应给客户端。注意,只有在第一次访问时,服务器才会创建session,给客户端响应sessionId。
- 当客户端再次访问服务器时,会在请求中带着sessionId给服务器,服务器通过sessionId到session池中找到session对象,这就可以完成会话跟踪了。也就是说,服务器端保存的是session对象,而客户端只有sessionId。每次访问都需要通过客户端的sessionId来匹配服务器端的session对象!这样用户在session中保存的数据就可以再次被使用了。

sessionId是服务器通过Cookie发送给客户端浏览器的,这个Cookie的maxAge为-1,即只在浏览器内存中存在。如果关闭所有浏览器窗口,那么这个Cookie就会消失了

### 典型应用:购物车

购物车可以分为内存购物车和持久化购物车两种,一般持久化购物车会使用MongoDB之类的非关系型数据库存储购物车信息

1、定义购买项类,用于封装具体的商品和购买数量
@Data
public class ShopItem  implements Serializable {
    private Product product;
    private int num=1;
}

2、定义购物车类,用于存放用户的各种购买项

public class ShopCart implements Serializable {
    private Map<Long, ShopItem> items = new HashMap<>();

    public void add(Product product) {
        if (items.containsKey(product.getId())) {
            ShopItem item=items.get(product.getId());
            item.setNum(item.getNum()+1);
        } else {
            ShopItem item = new ShopItem();
            item.setProduct(product);
            items.put(product.getId(), item);
        }
    }
}

3、Servlet接收所购买的商品编号,加入购物车
    public void addCart(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String ss=request.getParameter("id");
        Long id=null;
        try{
            id=Long.parseLong(ss.trim());
            Product product=productDao.loadById(id);
            ShopCart cart=new ShopCart();
            HttpSession session= request.getSession();
            Object obj=session.getAttribute("mycart");
            if(obj!=null && obj instanceof ShopCart)
                cart=(ShopCart) obj;
            if(product!=null)
                cart.add(product);
            session.setAttribute("mycart",cart);
        } catch (Exception e){
            id=null;
        }
        response.sendRedirect("product.do?action=showCart");
    }

4、显示购物车中的商品、价格和添加的数量
public void showCart(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.getRequestDispatcher("/cart/show.jsp").forward(request,response);
}

定义显示页面

<%
        Object obj = session.getAttribute("mycart");
        if (obj != null && obj instanceof ShopCart) {
            ShopCart cart = (ShopCart) obj;
            Collection<ShopItem> items=cart.getAllItems();
            for(ShopItem tmp:items){
    %>
    <tr>
        <th><%=tmp.getProduct().getId()%></th>
        <th><%=tmp.getProduct().getName()%></th>
        <th><%=tmp.getProduct().getPrice()%></th>
        <th><%=tmp.getNum()%></th>
        <th><%=tmp.getAllPrice()%></th>
        <th>
            <input type="button" value="删除"/>
        </th>
    </tr>
    <%}%>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值