Servlet – HttpSession 登录和注销及使用JavaScript定时刷新会话防止会话服务器过期及无活动超时自动注销示例

一般来说,计算语言中的术语“会话”是指用户活动在网站上发生的一段时间。每当您登录应用程序或网站时,服务器都应验证/识别用户并跟踪整个应用程序中的用户交互。为了实现这一点,Java Web Server 支持称为 HttpSession 的 servlet 标准会话接口来执行所有与会话相关的活动。

HttpSession 接口

Java servlet在 javax.servlet.http 包中有HttpSession (I)。此界面提供了一种方法来识别超过一页请求或访问网站的用户。Servlet 容器使用此接口在 HTTP 客户端和 HTTP 服务器之间创建会话并存储有关该用户的信息。它提供了各种方法来操作有关会话的信息,例如,

  • 将会话对象与指定用户绑定。
  • 获取创建时间。
  • 要知道最后一次,用户在该会话中访问了该网站。
  • 使会话无效等。

创建会话

用户登录网站后,我们需要创建一个新会话。为此,我们需要使用 HttpServletRequest 接口中的 getSession() 方法。

1)HttpSession getSession():

HttpSession session = request.getSession();

此方法返回与此请求关联的当前会话。如果请求没有会话,它会创建一个。我们还可以使用 HttpServletRequest 接口中的 getSession(boolean create) 方法创建会话。

2)HttpSession getSession(布尔创建):

我们可以传递布尔参数——真或假。

获取会话(真):

HttpSession session = request.getSession(true);

此方法与 getSession() 相同,它返回与此请求关联的当前会话。如果请求没有会话,它会创建一个。

获取会话(假):

HttpSession session = request.getSession(false);

此方法返回与此请求关联的当前会话。如果请求没有会话,则返回 null。

使会话无效

一旦用户请求注销,我们需要销毁该会话。为此,我们需要在 HttpSession 接口中使用 invalidate() 方法。

无效无效():

HttpSession session = request.getSession();
session.invalidate();

在会话上调用此 invalidate 方法时,它会删除绑定到该会话的所有对象。

Servlet 登录-注销示例

我们将创建一个基本的 Servlet 程序来为经过验证的用户显示欢迎消息。

创建程序的步骤:

  • 在 Eclipse 中创建“动态 Web 项目 - Servlet_LoginLogout”。
  • 在 WEB-INF 文件夹下,创建一个 JSP 页面——“login.jsp”来获取用户的登录凭证。
  • 在 src 文件夹下,创建一个 Servlet——“LoginServlet.java”来处理登录请求并生成响应。
  • 在 WEB-INF 文件夹下,创建一个 JSP 页面——“welcome.jsp”,向用户显示欢迎消息。
  • 在 src 文件夹下,创建一个 Servlet——“LogoutServlet”来处理注销请求并生成响应。
  • 使用“运行方式 -> 在服务器上运行”运行程序。

项目结构

login.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
         pageEncoding="ISO-8859-1"%>
<!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=ISO-8859-1">
        <title>Login Page</title>
    </head>
    <body>

        <form action="login" method="post">

            <h3>Enter Login details</h3>

            <table>
                <tr>
                    <td>User Name:</td>
                    <td><input type="text" name="usName" /></td>
                </tr>
                <tr>
                    <td>User Password:</td>
                    <td><input type="password" name="usPass" /></td>
                </tr>

            </table>

            <input type="submit" value="Login" />

        </form>
    </body>
</html>

  • 在“login.jsp”中,我们有两个字段,用户名和密码。
  • 用户名输入类型指定为“文本”,即文本字段。
  • 密码字段输入类型指定为“密码”,这样当用户输入密码字段时,它会将字母隐藏为点。
  • 我们已经形成了动作“login”和方法“post”,所以当这个表单被提交时,它会映射到具有相同 URL 映射的 LoginServlet,并执行该 servlet 的“doPost”方法。

LoginServlet.java:


import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@WebServlet("/login")
public class LoginServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    public LoginServlet() {
        super();
    }

    // doPost() method
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        // Set the content type of response to "text/html"
        response.setContentType("text/html");

        // Get the print writer object to write into the response
        PrintWriter out = response.getWriter();

        // Get the session object
        HttpSession session = request.getSession();

        // Get User entered details from the request using request parameter.
        String user = request.getParameter("usName");
        String password = request.getParameter("usPass");

        // Validate the password - If password is correct,
        // set the user in this session
        // and redirect to welcome page
        if (password.equals("geek")) {
            session.setAttribute("user", user);
            response.sendRedirect("welcome.jsp?name=" + user);
        } // If the password is wrong, display the error message on the login page.
        else {
            RequestDispatcher rd = request.getRequestDispatcher("login.jsp");
            out.println("<font color=red>Password is wrong.</font>");
            rd.include(request, response);
        }
        // Close the print writer object.
        out.close();
    }
}

  • 在“LoginServlet.java”中,我们使用注解“@WebServlet(“/login”)”来映射 URL 请求。您还可以使用部署描述符 - web.xml 为 servlet 指定此映射。
  • 我们了解到,获取 HttpSession 的会话对象。如果请求没有会话,它会创建一个会话并返回它。
  • 在这里,我们需要使用请求对象上的“getParameter()”来获取通过请求传递的用户详细信息、名称和密码。
  • 为简单起见,我们只是验证密码字段。所以,用户名可以是任何东西,但密码必须是“geek”。
  • 验证密码,如果正确,在会话中设置此属性值并重定向页面以显示欢迎消息。
  • 如果输入的密码不正确,请使用 Print writer 对象在登录屏幕中向用户显示错误消息。

欢迎.jsp:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
         pageEncoding="ISO-8859-1"%>
<!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=ISO-8859-1">
        <title>Welcome Page</title>
        <script src="jquery.min.js"></script>
        <script>
            var lastActiveTime = new Date().getTime();
            $(document).ready(function () {
                $('body').bind('click mousemove keypress scroll resize', function () {
                    lastActiveTime = new Date().getTime();
                });
                setInterval(checkIdleTime, 30000); // 30 sec
            });

            function checkIdleTime() {
                var diff = new Date().getTime() - lastActiveTime;
                if (diff > 120000) {//2 min of inactivity
                    window.location.href = "logout?msg=onTimeOut"

                } else {
                    $.ajax({url: 'refreshSession', error: function (data, status, xhr) {
                            alert("cannot refresh session on server: " + xhr);
                            window.location.reload();
                        }
                    });
                }
            }
        </script>
    </head>
    <body>

        <form action="logout" method="get">

            <h2>
                Hello
                <%=request.getParameter("name")%>!
            </h2>
            <h3>Welcome to GeeksforGeeks..</h3>

            <br> <input type="submit" value="Logout" />
        </form>

    </body>
</html>
  • 在欢迎页面上,显示用户名和欢迎消息。
  • 我们有一个带有动作“logout”和方法“get”的表单,所以当这个表单被提交时,它与具有相同 URL 映射的 LogotServlet 进行映射,并执行该 servlet 的“doGet”方法。

LogoutServlet.java:


import java.io.IOException;
import java.io.PrintWriter;

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

@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    public LogoutServlet() {
        super();
    }

    // doGet() method
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        // Get the print writer object to write into the response
        PrintWriter out = response.getWriter();

        // Set the content type of response to "text/html"
        response.setContentType("text/html");

        // For understanding purpose, print the session object in the console before
        // invalidating the session.
        System.out.println("Session before invalidate: " + request.getSession(false));

        // Invalidate the session.
        request.getSession(false).invalidate();

        // Print the session object in the console after invalidating the session.
        System.out.println("Session after invalidate: " + request.getSession(false));

        // Print success message to the user and close the print writer object.
        out.println("Thank you! You are successfully logged out.");
        out.close();
    }

}

  • 在这里,我们也使用注解“@WebServlet(“/logout”)”来映射 URL 请求。
  • 当用户单击注销时,我们需要销毁该会话。因此,在该会话对象上调用“invalidate()”方法。
  • 为了我们的理解,我们可以在控制台打印会话对象值,看看会话是否失效。
  • 正如我们所了解的,“getSession(false)”会根据请求返回当前会话(如果存在),如果不存在则返回 null。因此,在使会话无效后,它应该在控制台中打印 null。
  • 最后,将成功消息打印给用户。

刷新会话Servlet
 


import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@WebServlet(name = "refreshServlet", urlPatterns = {"/refreshSession"})
public class RefreshSessionServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req,
            HttpServletResponse resp) {

        System.out.println("refreshing session");

        HttpSession session = req.getSession();
        if (session == null) {
            System.err.println("cannot renew session");
        }
    }
}

会话监听器Listener



import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

@WebListener
public class MySessionListener implements HttpSessionListener {
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        System.out.println("-- HttpSessionListener#sessionCreated invoked --");
        HttpSession session = se.getSession();
        System.out.println("session id: " + session.getId());
        session.setMaxInactiveInterval(120);//in seconds
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        System.out.println("-- HttpSessionListener#sessionDestroyed invoked --");
    }
}

输出:

  • 在服务器上运行程序。
  • 网址:http://localhost:8081/Servlet_LoginLogout/login.jsp

登录页面

  • 浏览器显示登录页面。

使用用户详细信息登录

  • 输入用户名和密码,然后单击登录。
  • 将密码设置为“geek”,因为我们正在对其进行验证,否则会引发如下错误。

密码错误

  • 输入正确的凭据并登录。

欢迎页面

  • 我们在会话对象中设置的用户名会显示一条欢迎消息。
  • 单击注销。

注销_成功

  • 现在,如果您检查控制台,它会打印会话对象值。

安慰

  • 如您所见,“getSession()”返回了现有的会话对象。
  • 在 invalidate 方法之后,由于没有会话,它返回“null”。

注销用户的替代方法

1)在上面的例子中,我们使用了“invalidate()”方法,也可以在HttpSession接口中使用“removeAttribute(String name)”方法。

HttpSession session = request.getSession();
session.removeAttribute("user");

此方法从会话中删除与指定名称绑定的对象,在本例中为“用户”。如果会话没有与指定名称绑定的对象,则它什么也不做。因此,您可以使用“removeAttribute(String)”从会话中注销用户,而不是“invalidate()”方法。

2)在上面的例子中,我们手动使会话无效。如果需要,您还可以指定会话在定义的时间段内不活动后自动超时。

“无效 setMaxInactiveInterval(int 间隔)”:

HttpSession session = request.getSession();
session.setMaxInactiveInterval(100);

此方法指定 servlet 容器使该会话无效之前客户端请求之间的时间(以秒为单位)。在这里,由于我们指定了值“100”,会话将在用户的 100 秒不活动时间后失效。Servlet 容器将在 100 秒不活动后销毁会话 - 会话超时。

结论

通过这种方式,您可以为特定用户/客户端维护会话,并可以根据需求使用 HttpSession 接口方法为应用程序实现登录和注销。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值