JAVA零基础入门6-实现游客拦截功能

作为一个系统,存在有很多不想让访问进入的页面,如果任何人都可以访问到我们的操作页面,那么账号密码就失去了意义,因此,完成账户密码登录后,应增加一个登录拦截的功能,没有登录的用户只能访问到我们的登录注册页面

2023/11/7

1.编写一个过滤器

要实现登录拦截的功能,首先我们要先编写一个注册器,过程是所有的请求都要先经过我们的过滤器处理后,才能进入到指定资源,在写好的filter类中使用@WebFilter 并且在启动类中使用@ServletComponentScan扫描我们的filter,即可实现过滤请求的功能,下面是具体的代码编写:

@WebFilter(urlPatterns = "/*")
public class AuthFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        String path = req.getRequestURI().substring(req.getContextPath().length());//在URI中过滤上下文路径
        // 检查会话中是否有用户,且请求不是登录页面或静态资源
        if (path.startsWith("/login") ||path.startsWith("/register")||path.startsWith("/toregister")||path.endsWith("/")) {
            chain.doFilter(request,response);
        }else{
            //检查session
            HttpSession session = req.getSession(false);//这里false的作用是不新建session
            if (session == null || session.getAttribute("USER") == null) {
                String encodeMessage = URLEncoder.encode("请登录后重试","UTF-8");
                res.sendRedirect(req.getContextPath() + "/login"+"?message="+encodeMessage);

            } else {
                chain.doFilter(request, response);
            }
        }

    }
}

在这里,我设置了所有根路径下的请求都要经过过滤,我们定义了一个AuthFilter也就是验证过滤,这里一定要implements Filter代表它是一个filter的实现类,然后重写他的dofilter方法,其中的参数是dofilter中自带的,具有一个servlet请求和响应,以及filterchain 过滤链,

首先我们将servlet强制转换为Http类型,然后获取一个当前路径,这里geturi是除了com后面的路径(也就是8080后面的),而我们需要的是一个单独的映射路径,所有需要去掉一个上下文路径,上下文路径的获取方式是req.getContentPath,举个例子就是

http://www.example.com/myapp/homepage?user=guest

这里/myapp/homepage就是URI,然后去掉上下文路径/myapp,我们只保留homepage,将其设置为path,如果path不是login或者register,我们允许游客访问的路径我们就要进行处理,如果是,那就放行,使用chain.dofilter,进入下一个过滤链,或者到达访问资源。如何进行处理,首先,我们定义一个session,将参数值设置为false,这个目的是,如果用户没有session那么我们不必为他新建一个session,节省资源,判断session是否为空,或者user不存在,也就是还没登录或者没有这个用户,那就重定向到login路径,并且返回一个message,这里的message我们是通过url 的形式返回的,因此需要实现encode一下

实现效果如下:
当我们输入index想要跳过登录进入系统时,

请求会进入我们的过滤器并拦截他

2023/11/8

2.将session会话存储到redis

前言:redis缓存数据库相比mysql来说具有更快的响应速度,并且可以设置TTL过期时间,将session会话放到缓存redis中是常见的策略,可以使得一段时间内登录过的用户无需重复验证

在springboot中有一个session管理的功能,首先我们导入相关的pom依赖

   <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

然后在配置文件中配置redis

spring.data.redis.port=6379
spring.data.redis.database=1

最后我们需要定义一个配置类,用来将其注册为一个bean,可以被springboot所管理

@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 300)
public class RedisSessionConfig {
}

其中@EnableRedisHttpSession这个注解用于开启Spring Session的支持,并且指定session数据存储在Redis中。

做完这些,我们就可以正常在controller中使用session了

session.setAttribute("USER",username);

例如之前,我们在匹配过用户密码后给session的USER属性设置了一个值,可以在redis中显示出来,这里我们使用了一个redisinsight可视化软件,具体展现如下:


其中TTL我们设置的是每个会话存储300s,在300s内用户访问任何页面无需重新验证,300s后session消失,dofilter方法会重新导向到登录页面,自此完成了登录验证拦截并且存在过期时间的所有功能。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值