SessionFilter中获取token

业务场景:
在实际请求中,应当对每一个请求的合法性进行验证,保证请求的正确。而我在使用过程中使用的为spring+spring mvc+mybatis结合使用,所有就理所应当的使用spring mvc的过滤器来充当这个路径过滤的执行者。
在使用遇到的第一个问题:
过滤器实例如何实例化以及如何在启动时如何执行过滤?
查阅资料(连接
一、自定义过滤器实现过滤,继承OncePerRequestFilter类

@Component
public class SessionFilter extends OncePerRequestFilter implements Filter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        //不过滤的uri
        String[] notFilter = new String[]{"/login","/lib","/static","/ping"};

        //请求的uri
        String uri = request.getRequestURI();
        System.out.println("filter>>>uri>>>"+uri);

        //是否过滤
        boolean doFilter = true;
        for(String s : notFilter){
            //在给定符串中查找另一个字符串
            if(uri.indexOf(s) != -1){
                //uri中包含不过滤uri,则不进行过滤
                doFilter = false;
                break;
            }
        }

        if(doFilter){
            System.out.println("doFilter>>>");
            //过滤操作
            //从session中获取登陆者实体
            Object obj = request.getSession().getAttribute("token");

            if(obj==null){
                //todo
                System.out.println("doFilter>>>obj is null");
            }else{
//              对象实体存在,执行的操作
//              验证token是否合法
                String token = (String) obj;
                 if(token==null){
                 response.sendRedirect("/login");
                    //跳转到登录页面
                    return ;
                 }
                // 如果session中存在登录者实体,则继续
                filterChain.doFilter(request, response);
            }
        }else
            //不执行过滤操作
            filterChain.doFilter(request, response);
        }
    }
  
}

二、在web.xml中告知此过滤器。

<filter>
        <filter-name>DelegatingFilterProxy</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        <init-param>
            <param-name>targetBeanName</param-name>
            <param-value>SessionFilter</param-value>
        </init-param>
        <init-param>
            <param-name>targetFilterLifecycle</param-name>
            <param-value>true</param-value>
        </init-param>
        
    </filter>

到此完成了基本的spring mvc的filter基本的拦截。(这里我使用的redis作为缓存来存放token。)
下面就要从缓存中获取token,进行对比验证请求的合法性。
一开始,我使用spring的注解初始化实例,我想在过滤器中得到redis实例进行token的获取。经过几次的操作,都是报错了。通过在控制台进行实例的打印,发现并没有生成实例。所以问题了,为什么没有生成实例?

最后在我的不懈努力下,解决了。

一、使用spring-jedis.xml配置SessionFilter中Jedis实例,如下

    <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <!-- 最大连接数 -->
        <property name="maxTotal" value="${redis_maxTotal}"/>
        <!-- 最大空闲连接数 -->
        <property name="maxIdle" value="${redis_maxIdle}"/>
        <!-- 最小空闲连接数 -->
        <property name="minIdle" value="${redis_minIdle}"/>
        <!-- 每次释放连接的最大数目 -->
        <property name="numTestsPerEvictionRun" value="${redis_numTestsPerEvictionRun}"/>
        <!-- 释放连接的扫描间隔(毫秒) -->
        <property name="timeBetweenEvictionRunsMillis" value="${redis_timeBetweenEvictionRunsMillis}"/>
        <!-- 连接最小空闲时间 -->
        <property name="minEvictableIdleTimeMillis" value="${redis_minEvictableIdleTimeMillis}"/>
        <!-- 连接空闲多久后释放, 当空闲时间>该值 且 空闲连接>最大空闲连接数 时直接释放 -->
        <property name="softMinEvictableIdleTimeMillis" value="${redis_softMinEvictableIdleTimeMillis}"/>
        <!-- 获取连接时的最大等待毫秒数,小于零:阻塞不确定的时间,默认-1 -->
        <property name="maxWaitMillis" value="${redis_maxWaitMillis}"/>
        <!-- 在获取连接的时候检查有效性, 默认false -->
        <property name="testOnBorrow" value="${redis_testOnBorrow}"/>
        <!-- 在空闲时检查有效性, 默认false -->
        <property name="testWhileIdle" value="${redis_testWhileIdle}"/>
        <!-- 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true -->
        <property name="blockWhenExhausted" value="${redis_blockWhenExhausted}"/>

    </bean>

<!--连接池配置-->
    <bean id="jedisPoolAdmin" class="redis.clients.jedis.JedisPool">
        <constructor-arg name="poolConfig" ref="poolConfig"/>
        <constructor-arg name="host" value="${redis_admin_ip}"/>
        <constructor-arg name="port" value="${redis_port}"/>
        <!--超时时间-->
        <constructor-arg name="timeout" value="${redis_timeout}"/>
        <constructor-arg name="password" value="${redis_admin_auth}"/>
        <constructor-arg name="database" value="${redis_admin_database}"/>
    </bean>
    <!--实例连接池配置-->
    <bean id="JedisClientImplAdmin" class="tbcloud.admin.until.JedisClientImplAdmin">
        <property name="jedisPool" ref="jedisPoolAdmin"></property>
    </bean>
    <!--redis实例配置-->
<bean id="SessionFilter" class="tbcloud.admin.filter.SessionFilter">

        <property name="jedisClient" ref="JedisClientImplAdmin"></property>

    </bean>

二、SessionFilter中redis实例配置:

private JedisClient jedisClient;

    public JedisClient getJedisClient() {
        return jedisClient;
    }

    public void setJedisClient(JedisClient jedisClient) {
        this.jedisClient = jedisClient;
    }

至此,在SessionFilter中得到redis实例,可以进行jedis的操作了。
https://blog.csdn.net/xiaoyi52/article/details/76686001)
经过测试,此时是可以拿到spring中的redisTemplate 这个bean的,说明spring容器确实先于过滤器初始化的。那么回到过滤器中不能注入bean的问题,原因究竟是什么呢?可以看到,这里获取bean是通过applicationContext获取的,而不是直接注入的。个人理解是:过滤器是servlet规范中定义的,并不归spring容器管理,也无法直接注入spring中的bean(会报错)。当然,要想通过spring注入的方式来使用过滤器也是有办法的,先在web.xml中定义(保证filter在spring中初始化)

   <filter>
        <filter-name>DelegatingFilterProxy</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        <init-param>
            <param-name>targetBeanName</param-name>
            <param-value>SessionFilter</param-value>
        </init-param>
        <init-param>
            <param-name>targetFilterLifecycle</param-name>
            <param-value>true</param-value>
        </init-param>
        
    </filter>

参照上面配置redis实例。至此完成了token的较,保证请求的合法性————————————>哦也!!!!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值