springmvc验证登录用过滤器还是拦截器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springmvc验证登录用过滤器还是拦截器相关的知识,希望对你有一定的参考价值。

参考技术A 先执行filter,只有限制性过滤器之后才可以进入容器执行拦截 参考技术B spring面向切面呗,所以对于拦截器试用更加契合。 参考技术C 都用吧,强保险

SpringMVC -- 拦截器(作用与过滤器的区别示例拦截器实现登录拦截核心代码)

1. 拦截器


1.1 拦截器的作用


1.2 拦截器和过滤器的区别

过滤器可以过滤静态资源(HTML,JS,img…),而拦截器只会拦截控制器方法。


1.3 拦截器快速入门

自定义拦截器很简单,只有如下三步:

  1. 创建拦截器类实现Handlerlnterceptor接口
  2. 配置拦截器
  3. 测试拦截器的拦截效果

1.3.0 准备工作

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

TargetController.java

package com.itheima.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class TargetController {
    @RequestMapping("/target")
    public ModelAndView show() {
        System.out.println("目标资源执行......");
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("name", "TianJiao01");
        modelAndView.setViewName("index");
        return modelAndView;
    }
}


index.jsp

<html>
<body>
<h2>Hello World! ${name}</h2>
</body>
</html>

error.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>error</h1>
</body>
</html>

1.3.1 编写2个拦截器(待会演示配置文件顺便配置多个拦截器)


MyInterceptor1.java

package com.tian.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

public class MyInterceptor1 implements HandlerInterceptor {
    //在目标方法执行之前 执行(用的最多)
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
        System.out.println("preHandle.....");
        String param = request.getParameter("param");
        if ("yes".equals(param)) {
            return true;
        } else {
            request.getRequestDispatcher("/error.jsp").forward(request, response);
            return false;//返回true代表放行  返回false代表不放行
        }
    }

    //在目标方法执行之后 视图对象返回之前执行(一般用于对ModelAndView做修改动作)
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
    // 这里设置的同名的属性会覆盖controller方法的设置的属性
        modelAndView.addObject("name", "itheima02");
        System.out.println("postHandle...");
    }

    //在流程都执行完毕后 执行
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        System.out.println("afterCompletion....");
    }
}

MyInterceptor2.java

package com.tian.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

public class MyInterceptor2 implements HandlerInterceptor {
    //在目标方法执行之前 执行
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
        System.out.println("preHandle22222.....");
        return true;
    }

    //在目标方法执行之后 视图对象返回之前执行
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        System.out.println("postHandle2222...");
    }

    //在流程都执行完毕后 执行
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        System.out.println("afterCompletion2222....");
    }
}

1.3.2 配置拦截器


spring-mvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
">

    <!--1、mvc注解驱动-->
    <mvc:annotation-driven/>

    <!--2、配置视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--3、静态资源权限开放-->
    <mvc:default-servlet-handler/>

    <!--4、组件扫描  扫描Controller-->
    <context:component-scan base-package="com.tian.controller"/>


    <!--本节重点:配置拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--对哪些资源执行拦截操作  这里是拦截所有的请求-->
            <mvc:mapping path="/**"/>
            <bean class="com.tian.interceptor.MyInterceptor2"/>
        </mvc:interceptor>
        <mvc:interceptor>
            <!--对哪些资源执行拦截操作 这里是拦截所有的请求-->
            <mvc:mapping path="/**"/>
            <bean class="com.tian.interceptor.MyInterceptor1"/>
        </mvc:interceptor>
    </mvc:interceptors>
</beans>

1.3.3 逻辑说明

用户配置并启动Tomcat服务器后,如果直接输入/target去跳转到index.jsp页面,则会因为没有携带或者param参数值不为yes,而跳到error页面。用户在controller设置了name属性,但因为拦截器1也设置了name属性,所以controller设置的name属性会被覆盖。


1.4 运行结果


1.5 拦截器实现登录拦截核心代码

package com.itheima.interceptor;

import com.itheima.domain.User;
import org.springframework.web.servlet.HandlerInterceptor;

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

public class PrivilegeInterceptor implements HandlerInterceptor {

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
        // 前端登录成功后,需要向session里面存一个user
        // 逻辑:判断用户是否登录  本质:判断session中有没有user
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("user");
        if (user == null) {
            //没有登录
            response.sendRedirect(request.getContextPath() + "/login.jsp");
            return false;
        }
        //放行  访问目标资源
        return true;
    }
}


以上是关于springmvc验证登录用过滤器还是拦截器的主要内容,如果未能解决你的问题,请参考以下文章

一个网站的权限管理,用过滤器还是拦截器更好

SpringMVC拦截器在用户登录权限中的应用

spring mvc的拦截器的posthandle怎么用

简单使用拦截器

八 SpringMVC拦截器登录验证

SpringMVC -- 拦截器(作用与过滤器的区别示例拦截器实现登录拦截核心代码)