zoukankan      html  css  js  c++  java
  • SpringMVC:拦截器

    概述;

      过滤器和拦截器的区别? (拦截器是AOP思想的具体应用)

      过滤器:

        servlet规范中的一部分,任何javaWeb工程都可以使用

        在<url -parttern>中配置了/*后,可以对所有访问的资源进行拦截

      拦截器:

        拦截器是SpringMVC自己的,只有使用了SpringMVC框架的工程才能使用    

        拦截器只会拦截访问控制器(controller)的方法,如果访问的是jsp/html/css/image/js是不会进行拦截的

        拦截器是AOP思想的具体应用

    自定义拦截器:

      必须实现HandlerIntercepter接口

    小Demo,

    1.基础环境搭建

      1.1配置web.xml,(配置DispatcherServlet,请求分发器)

    <?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>springmvc</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:applicationContext.xml</param-value>
            </init-param>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>springmvc</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    </web-app>

      1.2,在spring的容器中(applicationContext)配置拦截器配置

        <!--拦截器配置-->
        <mvc:interceptors>
            <mvc:interceptor>
                <!--包括这个请求下面的所有请求-->
                <mvc:mapping path="/**"/>
                <bean class="com.king.config.MyInterceptor"/>
            </mvc:interceptor>
        </mvc:interceptors>

      1.2.1完整版spring容器基础配置,applicationContext

    <?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:context="http://www.springframework.org/schema/context"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            https://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/mvc
            https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    
    
        <context:component-scan base-package="com.king.controller"/>
        <!--静态资源过滤,不让静态资源走视图解析器-->
        <mvc:default-servlet-handler/>
    
        <!--注解驱动:dispatcherServlet,DefaultAnnotationHandlerMapping:处理器,作用在类上,处理请求映射的,相应的用户请求传递给相应的Controller类中
                    AnnotationMethodHandlerAdapter:适配器,作用在方法上,功能与上相似、找相应的方法-->
        <!--视图解析器-->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
              id="internalResourceViewResolver">
            <!--前缀-->
            <property name="prefix" value="/WEB-INF/jps/"/>
            <!--后缀-->
            <property name="suffix" value=".jsp"/>
        </bean>
    
        <!--解决json乱码问题-->
        <mvc:annotation-driven>
            <mvc:message-converters register-defaults="true">
                <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                    <constructor-arg value="UTF-8"/>
                </bean>
                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                    <property name="objectMapper">
                        <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                            <property name="failOnEmptyBeans" value="false"/>
                        </bean>
                    </property>
                </bean>
            </mvc:message-converters>
        </mvc:annotation-driven>
    
        <!--拦截器配置-->
        <mvc:interceptors>
            <mvc:interceptor>
                <!--包括这个请求下面的所有请求-->
                <mvc:mapping path="/**"/>
                <bean class="com.king.config.MyInterceptor"/>
            </mvc:interceptor>
        </mvc:interceptors>
    
    </beans>

    2.编写一个Controller类,用来模拟用户请求

    package com.king.controller;
    
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class TestController {
        @GetMapping("/t1")
        public String test(){
            System.out.println("testController方法执行了");
            return "OK";
        }
    }

    3.编写实现拦截器接口类,HandlerInterceptor

    package com.king.config;
    
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class MyInterceptor implements HandlerInterceptor {
    
        //return true;执行下一个拦截器,放行
        //return false;不执行下一个拦截器
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("=======处理前========");
            return true;
        }
    
        //此处一般写拦截日志
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println("=======处理后========");
        }
    
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            System.out.println("=======清理========");
        }
    }

    小demo,利用springmvc的拦截器实现用户登录,当非法登陆时时会被拦截器拦截

    非法登录:跳过登录请求直接进入用户页面(待更)

     拦截器作用,让非法请求不执行
    1.jsp页面

      1.1首页(未登录的页面)

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
      <head>
        <title>$Title$</title>
      </head>
      <body>
      <h1><a href="${pageContext.request.contextPath}/user/goLogin">登录</a></h1>
      <h1><a href="${pageContext.request.contextPath}/user/main">首页</a></h1>
      </body>
    </html>

      1.2登陆页面

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>登陆</title>
    </head>
    <body>
    
    <%--在web-inf下的所有页面或者资源,只能通过controller,或者servlet进行访问--%>
    <form action="${pageContext.request.contextPath}/user/login" method="post">
        用户名:<input type="text" name="name"><div>${error}</div>
        密码:<input type="text" name="pwd">
        <input type="submit" value="提交"/>
    </form>
    
    
    </body>
    </html>

      1.3登录成功页面

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
    
        <title>欢迎</title>
    
    </head>
    <body>
    
    
    <h1>欢迎!<span>${name}</span></h1>
    
    <p>
        <a href="${pageContext.request.contextPath}/user/goOut">注销</a>
    </p>
    
    </body>
    </html>

    2.Contrller层

    package com.king.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.servlet.http.HttpSession;
    
    @Controller
    @RequestMapping("/user")
    public class LoginController {
    
        @RequestMapping("/main")
        public String main(){
            return "main";
        }
    
        @RequestMapping("/goLogin")
        public String login(){
            return "login";
        }
    
        @RequestMapping("/login")
        public String login(HttpSession session, String name, String pwd, Model model){
            String username="king";
            session.setAttribute("nameInfo",name);
            if (name.equals(username)){
            model.addAttribute("name",name);
            return "main";
            }
            model.addAttribute("error","错误请重新输入");
            return "login";
    
        }
    
        @RequestMapping("/goOut")
        public String login(HttpSession session){
    
            session.removeAttribute("nameInfo");
    
            return "login";
    
        }
    
    
    
    }

    3.拦截器

    注:拦截器,必须实现HandlerInterceptor接口,重写里面的方法

    package com.king.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.servlet.http.HttpSession;
    
    @Controller
    @RequestMapping("/user")
    public class LoginController {
    
        @RequestMapping("/main")
        public String main(){
            return "main";
        }
    
        @RequestMapping("/goLogin")
        public String login(){
            return "login";
        }
    
        @RequestMapping("/login")
        public String login(HttpSession session, String name, String pwd, Model model){
            String username="king";
            session.setAttribute("nameInfo",name);
            if (name.equals(username)){
            model.addAttribute("name",name);
            return "main";
            }
            model.addAttribute("error","错误请重新输入");
            return "login";
    
        }
    
        @RequestMapping("/goOut")
        public String login(HttpSession session){
    
            session.removeAttribute("nameInfo");
    
            return "login";
    
        }
    
    
    
    }

    小结:

      1.拦截器时springmvc的,只有走SpringMVC框架的请求才会被拦截

      2.想使用拦截器,必须实现HandlerInterceptor接口

    HandlerInterceptor的方法:

    preHandle 

    调用时间:Controller方法处理之前

    执行顺序:链式Intercepter情况下,Intercepter按照声明的顺序一个接一个执行

    若返回false,则中断执行,注意:不会进入afterCompletion

    postHandle

    调用前提:preHandle返回true

    调用时间:Controller方法处理完之后,DispatcherServlet进行视图的渲染之前,也就是说在这个方法中你可以对ModelAndView进行操作

    执行顺序:链式Intercepter情况下,Intercepter按照声明的顺序倒着执行

    备注:postHandle虽然post打头,但post、get方法都能处理

    afterCompletion

    调用前提:preHandle返回true

    调用时间:DispatcherServlet进行视图的渲染之后

    多用于清理资源

      

       

      

        

      

  • 相关阅读:
    2月2日学习记录
    Python爬虫学习(三)使用Scrapy库
    2月1日学习记录
    Python爬虫学习(二)使用re库
    Python爬虫学习(二)使用Beautiful Soup库
    Python爬虫学习(一)使用requests库和robots协议
    spark学习(五)RDD
    body内常用标签--form表单
    body内常用标签
    HTTP协议
  • 原文地址:https://www.cnblogs.com/CL-King/p/13991398.html
Copyright © 2011-2022 走看看