栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring MVC拦截器1:拦截器入门一:拦截器(interceptor)简介;拦截器开发流程简介;演示了拦截器最基本的配置流程;

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring MVC拦截器1:拦截器入门一:拦截器(interceptor)简介;拦截器开发流程简介;演示了拦截器最基本的配置流程;

说明:

(1)本篇博客合理性解释:

          ● 本篇博客介绍Spring MVC中一个高级组件:拦截器;

          ● 但是,本篇博客的主要目的只是【引入Interceptor拦截器】、【简单的走一遍拦截器的配置过程】;

          ● 有关拦截器的【实用技巧】和【具体细节】等深入的内容在后面会介绍;即,本篇博客仅仅是拦截器的一个入门;

(2)本篇博客主要内容:

          ● 拦截器(Interceptor)简介;

          ● 拦截器(Interceptor)开发流程概述;

          ● 拦截器(Interceptor)开发流程走了一遍,演示了最初级的使用;

          ● 介绍了HandlerInterceptor接口的三个方法:preHandle()、postHandle()、afterCompletion();

(3)如有需要:过滤器(filter)可以参考【(5)常用功能与过滤器、监听器、FreeMarker;】专栏中的内容;Spring AOP可以参考【(15)Spring基础:IoC;AOP;JDBC;】专栏中的内容;

目录

一:拦截器简介;

二:拦截器(Interceptor)开发流程;

1. 拦截器(Interceptor)开发流程:简介;

2.开发前准备:准备一个【interceptor工程】;(这部分不是本篇博客的重点,快速扫过去就行)

(1)创建【interceptor】工程;

(2)【interceptor】工程,初始内容展示;

3.开发拦截器(Interceptor);(重点)

(1)第一步:在pom.xml中引入servlet-api依赖;

(2)第二步:新建一个实现了HandlerInterceptor接口的类;

(3)第三步:在applicationContext.xml中配置过滤地址;

(4)启动Tomcat,观察效果;


一:拦截器简介;

说明:

(1)拦截器的作用:拦截url,对其进行前置/后置过滤;

(2)【Spring中的拦截器】和【J2EE中的过滤器】,其作用有点类似,都是拦截请求;但是二者底层的实现逻辑是不同的;

          ● 拦截器(Interceptor)是Spring MVC的标准组件;(Interceptor对象被创建后,是天然的运行在IoC容器中的;)

          ● 过滤器(Filter)是J2EE的标准组件,是J2EE的标准;过滤器(Filter)的具体实现,是由不同的第三方容器厂商实现的;( 比如,我们在【过滤器一:过滤器简介;创建第一个Filter;】中直接使用的过滤器,就是Tomcat这个第三方厂商,根据J2EE标准实现的;)

(3)我们已经知道,拦截器(Interceptor)的作用是拦截url,对其进行前置/后置处理;

          ● 我们很容易就能联想到Spring中的【AOP面向切面编程】;

          ● 其实,拦截器(Interceptor)的底层最基本的实现,就是依赖于Spring AOP理念;(【拦截器(Interceptor)的具体实现】和【AOP中的环绕通知】很相似;)

……………………………………………………

(注)如有需要,过滤器(Filter)的有关内容可以参考【(5)常用功能与过滤器、监听器、FreeMarker;】的内容;Spring AOP的有关内容可以参考【(15)Spring基础:IoC;AOP;JDBC;】;


二:拦截器(Interceptor)开发流程;

1. 拦截器(Interceptor)开发流程:简介;

说明:

(1)拦截器(Interceptor)底层依赖于【最原始的servlet-api,也就是J2EE的javx.servlet】;所以,首先需要引入javax.servlet依赖;(至于为什么要引入Servlet依赖,在【附加:Java简介(Java SE,Java EE,JDK等);【java.servlet.**】和【javax.**】简介;Eclipse和IDEA在使用servlet-api.jar时的区别;】和本篇博客的后续内容中会得到答案;)

(2)新建一个类,然后这个类要实现HandlerInterceptor接口;(这个接口的完整地址是org.springframework.web.servlet.HandlerInterceptor,可以看到,这个接口是Spring定义的)

(3)然后,在编好了拦截器类后,需要在applicationContext.xml中配置过滤地址;

2.开发前准备:准备一个【interceptor工程】;(这部分不是本篇博客的重点,快速扫过去就行)

(1)创建【interceptor】工程;

首先,创建一Maven WebApp项目;

这个过程可以参考【SpringMVC入门与数据绑定2:Spring MVC初体验二:使用IDEA创建【maven + WebApp】项目;】;啰嗦一下吧,其基本过程就是:

     第一步:创建一Maven项目;

     第二步:将工程设置为Web工程;

          ● 添加web功能;

          ● 三个设置项:【设置web.xml文件目录】、【设置web资源保存目录】、【设置artifact发布】;

     第三步:给项目配置Tomcat;

          ● 配置一个本地的Tomcat服务器;

          ● 在Deployment中配置artifact发布;

          ● 设置一下Server中的端口号等内容;

……………………………………………………

然后,配置Spring MVC;

这个过程可以参考【SpringMVC入门与数据绑定3:Spring MVC初体验三:Spring MVC环境配置;(通过一个简单案例,走了一遍Spring MVC流程;)】,其基本过程就是:

     第一步:在pom.xml中引入依赖;

     第二步:在web.xml中配置DispatcherServlet;

     第三步:创建并编写applicationContext.xml;

     第四步:将新引入依赖添加到Tomcat发布中去;

……………………………………………………

至此,一个Spring MVC项目就创建好了;


(2)【interceptor】工程,初始内容展示;

pom.xml:



    4.0.0

    com.imooc
    interceptor
    1.0-SNAPSHOT

    
        
            aliyun
            aliyun
            https://maven.aliyun.com/repository/public
        
    

    
        
            org.springframework
            spring-webmvc
            5.1.9.RELEASE
        

        
            com.fasterxml.jackson.core
            jackson-core
            2.9.9
        
        
            com.fasterxml.jackson.core
            jackson-databind
            2.9.9
        
        
            com.fasterxml.jackson.core
            jackson-annotations
            2.9.9
        
    

……………………………………………………

web.xml:




    
        springmvc
        org.springframework.web.servlet.DispatcherServlet
        
            contextConfigLocation
            classpath:applicationContext.xml
        
        0
    
    
        springmvc
        /
    

    
        characterFilter
        org.springframework.web.filter.CharacterEncodingFilter
        
            encoding
            UTF-8
        
    
    
        characterFilter
        /*
    

    
        formContentFilter
        org.springframework.web.filter.FormContentFilter
    
    
        formContentFilter
        /*
    

……………………………………………………

Persons:

package com.imooc.restful.entity;

import com.fasterxml.jackson.annotation.JsonFormat;

import java.util.Date;

public class Person {
    private String name;
    private Integer age;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private Date birthday;

    public Person() {
    }

    public Person(String name, Integer age, Date birthday) {
        this.name = name;
        this.age = age;
        this.birthday = birthday;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}

……………………………………………………

RestfulController:

package com.imooc.restful.controller;

import com.imooc.restful.entity.Person;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/restful")
public class RestfulController {

    @GetMapping("/persons")
    public List findPersons() {
        List list = new ArrayList();
        Person person1 = new Person();
        person1.setName("zhang");
        person1.setAge(20);
        person1.setBirthday(new Date());
        Person person2 = new Person();
        person2.setName("wang");
        person2.setAge(21);
        person2.setBirthday(new Date());
        list.add(person1);
        list.add(person2);
        return list;
    }
}

……………………………………………………

applicationContext.xml:




    

    
        
            
                
                    
                        text/html;charset=utf-8
                        application/json;charset=utf-8
                    
                
            
        
    
    

    
        
    

……………………………………………………

client.html:




    
    Title
    
    


    
    
    
    
    



其实,【interceptor工程】就是照搬前面的【restful工程】; 

3.开发拦截器(Interceptor);(重点)

(1)第一步:在pom.xml中引入servlet-api依赖;
        
            javax.servlet
            javax.servlet-api
            3.1.0
            provided
        

说明:

(1)servlet依赖说明:

(2)第一次遇到,基于IDEA,在工程中引入servlet api是在【OA系统六:前期准备四:整合FreeMarker;引入Servlet3.1依赖;顺带设置下logback.xml日志;】;并且,当时也是把servlet的scope设置为了provided;

(3)一个疑问:Eclipse和IDEA在开发的时候,如果需要用到HttpServletRequest或者HttpServletResponse时,一个不需要引入javax.servlet依赖,一个需要引入javax.servlet依赖,这个问题还未解决,等会解决后,再补充;:在【附加:Java简介(Java SE,Java EE,JDK等);【java.servlet.**】和【javax.**】简介;Eclipse和IDEA在使用servlet-api.jar时的区别;】中有详细介绍;


(2)第二步:新建一个实现了HandlerInterceptor接口的类;

MyInterceptor类:

package com.imooc.restful.interceptor;

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 {
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //获取当前的url地址,打印一下示意性的信息;
        System.out.println(request.getRequestURL() + "请求还未进入Controller之前,执行preHandle()方法。");
        //如果返回return true;那么请求就会被送达给【后面的拦截器(如果还有的话)】,或者送给Controller;
        //如果返回return false;那么当前的请求就会被阻止,直接产生响应,返回给客户端;
        //即,这个return的结果,决定了当前请求是继续向后传递执行,还是立即结束、返回响应;
        return true;
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println(request.getRequestURL() + "Controller方法return以后,但还未产生响应文本之前,执行postHandle()方法。");
    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println(request.getRequestURL() + "响应文本产生后,执行afterCompletion()方法。");
    }
}

说明:

(1)HandlerInterceptor接口的完整地址是org.springframework.web.servlet.HandlerInterceptor,可以看到这个接口是Spring中定义的;

(2)HandlerInterceptor接口中的三个方法说明:这三个方法对应了三个不同的执行时机;

          ● preHandle():前置执行处理:意思是:一个请求产生后,在请求还未进Controller之前,先要执行preHandle()方法,对这个请求进行预置处理;

          ● postHandle():目标资源已被Spring MVC框架处理:意思是:【Controller的方法已经处理了请求,Controller方法return以后,但还未产生响应文本之前】,在这个时机执行postHandle()方法;

          ● afterCompletion():响应文本已经产生:意思是:产生了响应文本以后,afterCompletion()方法就会被自动执行;(如果Controller方法返回的是ModelAndView,那么数据和模板引擎混合后,会产生一个HTML片段,然后afterCompletion()方法就会被执行;;;;如果Controller方法返回的是一个需要被JSON序列化的对象,那么当jackson组件把这个对象序列化为JSON字符串后,afterCompletion()方法就会被执行)

          ● 这个三个方法在执行时,是按照时间顺序,有序执行的;

(3)preHandle()、postHandle()、afterCompletion()方法的参数,印证了为什么我们在第一步,要先引入servlet依赖;

(4)代码内容说明:

强调一些preHandle()方法的返回值问题:

          ● 首先,一个前提,一个项目可能有多个拦截器,即同一个请求可能会被多个拦截器处理,然后再传给Controller;

          ● 如果preHandle()方法,返回true的话:那么请求就会被送给后面的拦截器(如果还有的话),或者送给Controller;

          ● 如果preHandle()方法,返回false的话:那么当前的请求就会被阻止,直接产生响应,返回给客户端;

          ● 即,这个return的结果,决定了当前请求是继续向后传递执行,还是立即结束、返回响应;


虽然,上面写了实现了HandlerInterceptor接口的MyInterceptor类;但是,Spring MVC还不认识这个类的;我们需要在applicationContext.xml中对其进行配置,就是第三步的内容;

(3)第三步:在applicationContext.xml中配置过滤地址;
    
        
            
            
        
    

说明:

(1)内容说明:主要配置两项:【拦截哪些url】,【使用哪个类来处理,拦截到的url】;

其中, 【path="/**"】表示,拦截所有请求; 


(4)启动Tomcat,观察效果;

可以看到, preHandle()、postHandle()、afterCompletion()这三个方法的执行顺序,符合预期;

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/591102.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号