Servlet实现用户登录拦截功能

目录

1.创建一个Servlet项目

2.准备好Tomcat,用于启动Servlet项目 

3.检查Servlet项目的起始目录是否准备齐全

4.准备用户登录所需创建文件夹和文件

5.编写Jsp文件

login.jsp

error.jsp

Content.jsp

6.测试

7.题外:会话(session)功能


1.创建一个Servlet项目

在Idea中选择maven-archetype-webapp,点击创建(create)

注:此处Idea版本为2023,若是以往版本,页面会有不同,但找到maven项目一样可以找到

Servlet实现用户登录拦截功能_第1张图片

Servlet项目所需依赖

    
    
      javax.servlet
      javax.servlet-api
      4.0.0
      provided
    

2.准备好Tomcat,用于启动Servlet项目

创建本地(local)Tomacat,在菜单Server中选择对应的可使用的tomcat程序,此处用的版本为Tomcat.9.0.62,接着在Http port中设置服务器端口(默认为8080),配置完成后点击Apply

Servlet实现用户登录拦截功能_第2张图片

接着在菜单Deployment中添加要部署的项目,点击+号作添加,选择以war为后缀的项目文件,此处我的项目名称为ServletReview1,因此显示为ServletReview1:war;下面的Application context指的是基于8080端口下的映射路径,这里可以自定义作选择,我这里直接默认以/作为起始映射点

3.检查Servlet项目的起始目录是否准备齐全

一个基本的Servlet项目,包含蓝色的java文件(注:蓝色是表示该文件是源代码文件夹,用于存放所有与Java相关的代码文件,若不是蓝色,则需点击右键-Mark directory as-Source-root)、resource资源文件(可以用于存放静态资源,如图片、视频、图标等)、webapp目录(注:该文件是有蓝色小圆点的,表示Tomcat启动后会默认被扫描到的地方)

Servlet实现用户登录拦截功能_第3张图片

注:如果你想手动配置一个webapp(带蓝点)的文件,则需要点击File-Project Structure-Modules-点击+号,然后用一个已有的web.xml的路径,将两者关联

Servlet实现用户登录拦截功能_第4张图片

4.准备用户登录所需创建文件夹和文件

此处根据自己的创建习惯,在java文件夹下自定义文件夹,一般我的习惯是Controller文件夹+Filter文件夹,分别用来编写Servlet和过滤器代码

写登录的逻辑代码,存在controller中(此处不添加数据库,模拟一套用户名和密码)

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class LoginServlet extends HttpServlet {

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

        super.doPost(req, resp);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");

        // 获取请求参数
        String username = req.getParameter("username");
        String password = req.getParameter("password");


            if ("admin".equals(username) && "123456".equals(password)) {
                System.out.println("登陆成功");
                // 倘若校验成功 则将其存在session中,便于到时在过滤器代码中取出作筛选
                HttpSession httpSession = req.getSession();
                httpSession.setAttribute("username",username);
                resp.sendRedirect("/jsp/Content.jsp");
            } else {

                String message = "登录失败,请检查用户名和密码";
                resp.getWriter().write("");

            }
        }
    }

写完一个Servlet后,马上在web.xml中作映射(避免遗忘的好习惯)

  
  
  
    
    LoginServlet
    
    zhan.controller.LoginServlet
  
  
  
    
    LoginServlet
    
    
    /LoginServlet
  

写过滤器代码

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class AuthenticationFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        // 根据您的登录验证逻辑判断用户是否已登录
        boolean isLoggedIn = checkLoginStatus(request);

        if (isLoggedIn) {
            // 用户已登录,继续执行下一个过滤器或请求(放行)
            filterChain.doFilter(request, response);
        } else {

            response.sendRedirect("/jsp/error.jsp");

        }
    }

    @Override
    public void destroy() {

    }

    private boolean checkLoginStatus(HttpServletRequest request) {
        // 在这里编写您的登录验证逻辑
        // 返回 true 表示已登录,返回 false 表示未登录
        // 这里只是一个示例,您需要根据您的实际情况进行修改
        HttpSession session = request.getSession(false);
        if (session != null) {
            // 获取session中的用户名,并打印检查
            System.out.println(session.getAttribute("username"));
            System.out.println(session);
        }
        return session != null && session.getAttribute("username") != null;
    }
}

然后跟Servlet一样的,Filter类也要在web.xml中作映射



  AuthenticationFilter
  
  zhan.Filter.AuthenticationFilter




  
  AuthenticationFilter
  
  /jsp/*

这个过滤器的作用是对所有以"/jsp/"开头的URL进行身份认证,如果用户未登录或登录信息不正确,则重定向到登录页面。可以看出,这个过滤器是在保护Web应用程序的安全方面起作用的。

注:这是一段典型的web.xml配置文件中的过滤器(filter)代码段,其中定义了名字为“AuthenticationFilter”的过滤器,该过滤器由“zhan.Filter.AuthenticationFilter”类实现。通过filter-mapping元素将此过滤器映射到所有以“/jsp/”开头的请求路径上。当请求的URL路径被匹配时,容器就会先调用该过滤器来进行身份认证,保障Web应用程序的安全性

5.编写Jsp文件

此处是我的webapp目录,其中web.xml是必须要在WEB-INF下的

Servlet实现用户登录拦截功能_第5张图片

我个人习惯是创建jsp文件夹,用于存放不同模块下的不同jsp页面,然后在webapp目录下直接创建一个登陆页面和错误页面(login.jsp和error.jsp),当然用index作登陆首页也没问题

由于我此处选择了用login作为首页,因此跟以往Servlet启动时,自动跳转到index.jsp不同的是,我需要在web.xml中额外作首页配置:

  
  
    login.jsp
  

配置完后,每次运行Servlet项目时,会先跳转到login.jsp页面

login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


登录



用户名:
密码:

error.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>



    
    无权限



请登录后再访问该页面!返回

Content.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--<%= session.getAttribute("username") %>--%>


    首页


<%= session.getAttribute("username")%>

hello world!

至此,一个基本的用户登录(带过滤)的代码工作基本完成

6.测试

登录:

Servlet实现用户登录拦截功能_第6张图片Servlet实现用户登录拦截功能_第7张图片

倘若登录失败:

Servlet实现用户登录拦截功能_第8张图片

倘若想跳过登录,直接访问路径:

则会响应过滤器,发现session中没有username,就跳转到error.jsp页面

Servlet实现用户登录拦截功能_第9张图片

7.题外:会话(session)功能

其中无论是在LoginServlet还是filter类中,都离不开会话session的功劳,在前者代码里,登录成功后将username存进了session里:

            if ("admin".equals(username) && "123456".equals(password)) {
                System.out.println("登陆成功");
                // 倘若校验成功 则将其存在session中
                HttpSession httpSession = req.getSession();
                httpSession.setAttribute("username",username);
                resp.sendRedirect("/jsp/Content.jsp");
            }

然后又在Filter类中,检查session里是否有username进而作筛选:

 private boolean checkLoginStatus(HttpServletRequest request) {
        // 在这里编写您的登录验证逻辑
        // 返回 true 表示已登录,返回 false 表示未登录
        // 这里只是一个示例,您需要根据您的实际情况进行修改
        HttpSession session = request.getSession(false);
        if (session != null) {
            // 获取session中的用户名,并打印检查
            System.out.println(session.getAttribute("username"));
            System.out.println(session);
        }
        return session != null && session.getAttribute("username") != null;
    }

基本上,一个Servlet项目往往离不开session:

Session(会话)是一种在Web应用程序中用于跟踪用户状态和存储用户相关信息的机制。在HTTP协议的无状态特性下,为了实现用户的连续性和数据的持久化,可以使用会话来跟踪用户在多个HTTP请求之间的状态。

其工作原理如下:

  1. 当用户首次访问Web应用程序时,服务器会为该用户创建一个唯一的会话标识,通常是一个会话ID。这个会话ID会被发送到用户的浏览器,并保存在cookie或URL参数中。

  2. 用户的每次请求都会携带会话ID,服务器通过会话ID来识别用户并检索与之关联的会话数据。

  3. 服务器可以在会话中存储用户的相关信息,例如登录状态、购物车内容等。这些信息可以在不同的页面和请求之间进行共享和传递,从而实现用户状态的保持。

  4. 会话的有效期可以根据需要进行设置,可以是固定的时间段,也可以是用户关闭浏览器时结束。

通过会话,Web应用程序可以实现以下功能:

  1. 用户认证和授权:会话可以跟踪用户的登录状态,确保只有经过身份验证的用户才能访问受限资源。
  2. 数据持久化:可以在会话中存储和获取用户的数据,以便在不同页面和请求之间进行传递和共享。
  3. 购物车管理:会话可以用于存储用户的购物车内容,并在用户提交订单时进行处理。
  4. 记录用户行为:可以通过会话来记录用户在网站上的操作和浏览历史,用于统计和个性化推荐等。

需要注意的是,由于会话是在服务器端进行管理的,因此需要在跨页面和跨请求之间正确传递会话ID。一般情况下,浏览器会自动处理这些细节,但在某些特殊情况下,可能需要手动管理会话ID的传递和处理。

我们也可以在web.xml中设置session的超时时间:


    30 

你可能感兴趣的:(Servlet,JavaWeb,Tomcat,servlet)