Servlet-会话

会话对象HttpSession

HttpSession是tomcat在服务器端为每个浏览器准备的私人储物箱,每个浏览器在tomcat里都有一个属于自己的HttpSession对象,用于存储私人数据。

在Servlet中可以通过request.getSession()方法来获得session对象,这个方法总是返回与发送请求的浏览器对应的session对象。

该方法是有这个对象则用这个对象,没有则创建。用来解决http无状态的问题。该对象保存在服务器中。

Session的私有性

在这里插入图片描述

利用session存取私人数据

与request对象一样,session对象也提供了存取数据的方法
session.setAttribute( “name”, object );
name : 数据的别名
object:存储的数据本身

Object session.getAttribute(“name”) ;
name :要获取的数据别名
返回值:与name对应的数据对象

Session对象的生命周期

创建 : 当用户第一次调用getSession(true)方法
销毁 : 用户长时间没有执行操作(timeout)
Tomcat默认的session超时为30分钟

Session的钝化与锐化:
当服务器内存空间紧张或tomcat关闭时,tomcat会将不活跃的session保存到磁盘中,当需要使用时或tomcat重新启动时再次加载到内存中来

Session与request

request
命名属性可以在由forward连接的多个servlet之间共享
生命周期较为短暂
当请求到达服务器时创建
当应答送回到浏览器时销毁

Sesison
命名属性可以在同一个浏览器的多次请求之间共享
生命周期较长
在调用request.getSession(true)时被创建
在超时之后被销毁

Session的实现机制

getSession()方法是如何将session对象与浏览器对应起来的?
Tomcat会为每个拥有session的浏览器设置一个特别的Cookie,称作会话Cookie.会话Cookie的名字固定叫做 “JSESSIONID”, Cookie的值就是该浏览器对应的session ID号,其生命周期为-1。
当调用getSession(true)时,他首先检查用户的会话Cookie是否存在
如果不存在 : 为其创建新的session对象,将session对象的ID保存到新建的会话Cookie中,并将会话cookie送回浏览器 。
如果存在 : 则按照会话Cookie 的值找到对应的session对象返回

Session对象使用实例

登陆成功后将登陆名存储到用户的session对象中
检查登陆的时候,就判断session对象中是否存储了用户的登陆名
如果sessoin保存了用户名:说明该用户已经登陆过
如果sesson没有保存用户名:说明该用户没有登陆

  1. 创建登录界面
    在这里插入图片描述
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
    <form action="test" method="post">
        账户:<input type="text" name="account"></br>
        密码:<input type="text" name="password"></br>
            <input type="submit" value="登录">
    </form>
</body>
</html>
  1. post方式进行登录验证将用户数据写入会话中
@Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("当前请求方式为post方式");
        response.setContentType("text/html;charset=utf-8");
        //设置请求对象编码 解决post方式的乱码问题
        request.setCharacterEncoding("utf-8");
        PrintWriter out = response.getWriter();
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        if (username.equals("zhangsan")&&password.equals("123456")){
            //创建会话,保存用户信息
            HttpSession session = request.getSession();
            //设置会话有效期,单位秒,默认有效期30分钟
            session.setMaxInactiveInterval(600);
            //保存用户帐号
            session.setAttribute("username",username);
            out.write("<h3>验证成功</h3> 欢迎:"+username+":<a href = \"index\">主页面</a>");

        }else {
            out.write("<h3 style=\"color:red;\">验证失败</h3>");
        }
        out.close();
    }
  1. 对会话进行验证
@WebServlet("/index")
public class IndexServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        HttpSession session = request.getSession();
        if (session.getAttribute("username")==null){
            out.write("请先登录,<a href=\"login.html\">登录</a>");

        }else {
            out.write("欢迎:"+session.getAttribute("username")+"<a href=\"logout\">注销</a>");
        }
    }
}

  1. 销毁会话
@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        //清空会话中的所有数据
        session.invalidate();
        //如果想移除单个数据可以使用removeAttribute()
//      session.removeAttribute("username");
        //重定向到登录界面
        response.sendRedirect("login.html");

    }
}

Cookie

Cookie是服务器保存在用户浏览器上的一段字符串
当浏览器向服务器发送请求时,会自动将这些浏览器存储的字符串发送到服务器
我们可以利用这些字符串记录用户的重要状态,如是否登录,用户权限等
在服务器端的Servlet中,通过检查这些字符串来判断用户的状态

如何将Cookie存储到浏览器

1、创建Cookie
2、设置Cookie的生命周期
3、将Cookie存储在用户的浏览器中

Session和Cookie的使用

@WebServlet("/session")
public class SessionServlet extends HttpServlet {
    /**
     * servlet生命周期的方法,可以处理所有方式的请求
     */
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //创建会话对象,如果存在使用原来的会话对象,如果不存在则创建新的会话对象。
        //会创建会话Cookie,把session的id写入客户的浏览器名称是jsessionid,只是session的id,浏览器下次访问时带上Cookie进行访问
        response.setContentType("text/html;charset=utf-8");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        HttpSession session = request.getSession();
        PrintWriter out = response.getWriter();
        out.write("会话id:" + session.getId() + "</br>");
        out.write("会话创建时间:" + sdf.format(new Date(session.getCreationTime())) + "</br>");
        out.write("系统当前时间:" + sdf.format(new Date()));

        //创建会话对象
        Cookie username = new Cookie("username", "zhangsang");
        Cookie password = new Cookie("password", "123456");
        //设置有效时间,单位是秒 不写默认-1(关闭浏览器后删除)
        username.setMaxAge(60);
        //把Cookie写入浏览器,返回给客户端,只有客户端成功响应之后才能将cookie写入浏览器
        response.addCookie(username);
        response.addCookie(password);

        //获取浏览器的Cookie
        Cookie[] cookies = request.getCookies();
        Arrays.stream(cookies).forEach(cookie -> {
            System.out.println("键:"+cookie.getName()+",值:"+cookie.getValue());
        });

        out.flush();
        out.close();//流关闭响应结束
    }
}

Cookie的特征

采用字符串的形式存储数据,简单灵活
存储在用户的浏览器上,减少对服务器的压力
对于重要数据而言,存储在浏览器上不够安全
无法存储格式复杂的数据格式,如对象,集合等

Cookie和Session的比较

Cookie是写在浏览器上的
Session是写在服务器上的

Servlet 通信方法

Servlet 访问网络资源以满足客户端请求
Servlet 使用 RequestDispatcher 接口的 forward() 和include() 方法访问网络资源

public void forward (ServletRequest req, ServletResponse res);
将请求从一个 Servlet 转送到同一个服务器上的另一个 Servlet

public void include (ServletRequest req, ServletResponse res);
在一个 Servlet 中包含另一个 Servlet 的内容

Servlet使用实例

Test1

@WebServlet("/test1")
public class Test01Servlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setAttribute("name","张三");
        //把请求转到/test2,客户端显示的还是第一个请求地址,因为请求转发是发生在服务器内部的事情,客户端不知情
        //是同一个请求对象中的转发,两个servlet可以共享request对象的数据
        request.getRequestDispatcher("/test2").forward(request,response);
    }
}

Test2

@WebServlet("/test2")
public class Test02Servlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("姓名:"+request.getAttribute("name"));
        //调用Test3Servlet的service方法
        request.getRequestDispatcher("test3").include(request,response);
        System.out.println("年龄:"+request.getAttribute("age"));
    }
}

Test3

@WebServlet("/test3")
public class Test03Servlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setAttribute("age","20");
    }
}

forward()方法个include()方法的区别

forward()方法是跳到另一个servlet去处理数据后面的语句不再执行,只能调用一次。
include()方法是调用另一个servlet的方法来获取数据,可以多次调用。

Servlet 上下文

将所有 Servlet 所共有的属性和资源存储于 ServletContext 接口对象。
服务器启动时创建,关闭时销毁
实例:
创建一个类demo01和类demo02,demo01往上下文添加数据,demo02读取数据

demo01:

@WebServlet("/demo01")
public class Demo01Servlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取上下文对象,该对象在服务器启动时创建,关闭时销毁
        ServletContext context = request.getServletContext();
        //在上下文对象设置值,所有servlet对象都能够取到。
        context.setAttribute("phone","138123456789");
        context.setAttribute("address","南宁市西乡塘区");
    }
}

demo02:

@WebServlet("/demo02")
public class Demo02Servlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取上下文对象,该对象在服务器启动时创建,关闭时销毁
        ServletContext context = request.getServletContext();
        //在上下文对象获取值
        System.out.println("电话:"+context.getAttribute("phone"));
        System.out.println("地址:"+context.getAttribute("address"));

    }
}

小结

 * servlet生命周期:
 * 单例模式,一个servlet类只创建一个对象,在客户端第一次请求时在服务器创建,用来处理客户端请求。
 * 内存不足或者服务器关闭时销毁
 * request生命周期:
 * 多例模式,每次请求创建一个对象,当请求到达服务器时由服务器创建,当服务器响应结束后返回客户端时销毁。
 * session生命周期
 * 客户端请求服务器调用getSession方法时由服务器创建,有效期超时或者服务器关闭销毁。
 * context生命周期
 * 单例模式:服务器启动时创建,服务器关闭时销毁。
 * Cookie生命周期
 * 服务器响应客户时由服务器创建,响应结束后返回返回客户端浏览器保存对象。
 * 如果设置有效期,有效期结束后由浏览器删除,默认是关闭服务器则删除。

总结

可以使用会话跟踪对客户端发出的一系列请求进行跟踪
不同的会话跟踪技术包括用户授权、隐藏表单字段、URL 重写和 Cookie
Servlet 使用 RequestDispatcher 接口的 forward() 和 include() 方法进行通信
Servlet 上下文用于存储不同 Servlet 的信息
ServletConfig 接口的 getServletContext() 方法用于配置 Servlet 上下文(获取上下文)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值