springboot之拦截器、servlet过滤器

拦截器与过滤器的区别

  •  归属不同:Filter属于Servlet技术,Interceptor属于SpringMVC技术
  •  拦截器内容不同:Filter对所有访问进行增强(在Tomcat服务器进行配置),Interceptor仅针对SpringMVC的访问进行增强

一 使用maven新建Spring Boot项目

1. File --> New --> Project... --> Maven ,如下图所示

Project SDK下拉列表框中选择前面安装的 Java1.8,如果下拉列表框中不存在Java 1.8,可以单击New按钮,找到安装Java的位置,选择它。至于Maven中的archetype,不用勾选。然后单击“Next”

2. 给新工程起名springboot-interceptor-and-servletfilter,配置GAV

 3.配置pom.xml

使用Maven,通过导入Spring Boot的 starter 模块,可以将许多程序依赖包自动导入工程中。使用Maven的parent POM,还可以更容易地管理依赖的版本和使用默认的配置,工程中的模块也可以很方便地继承它。使用如下代码清单所示的简单maven配置,基本上就能为一个使用Sping Boot开发框架的Web项目开发提供所需的相关依赖。
 

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>springboot-interceptor-and-servletfilter</artifactId>
    <version>1.0</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.12</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

4. 创建Controller

在src/main/java下新建三级目录com/practice/demo,在该目录下创建 DemoApplication,以该类作为程序主入口

DemoApplication Controller代码如下

package com.practice.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class,args);
    }

    @RequestMapping("/")
    public String hello() {
        return "Hello, baby!";
    }
}

运行该Spring boot应用。浏览器可访问,访问效果如下:

二 为Spring boot项目添加Servlet过滤器

Spring boot Servlet

过滤器是用于拦截应用程序的HTTP请求和响应的对象。通过使用过滤器,可以在两个实例上执行两个操作 -

  • 在将请求发送到控制器之前
  • 在向客户发送响应之前。
    以下代码显示了带有@Component注解的Servlet过滤器实现类的示例代码。




 

1. 在springboot项目 com.practice.demo目录下新建SimpleFilter类,该类实现 Filter 接口。

2. 在该实现类SimpleFilter的doFilter()方法中,添加 System.out.println()语句来打印运程主机和运程地址。

完整代码如下:

package com.practice.demo;

import org.springframework.stereotype.Component;

import javax.servlet.*;
import java.io.IOException;

@Component  //只有加了该注解,才会生效。不加不生效(但不会报错)
public class SimpleFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 可sout快速打出System.out.println()
        System.out.println("Remote Host:"+servletRequest.getRemoteHost());
        System.out.println("Remote Address:"+servletRequest.getRemoteAddr());
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

    }
}

3. 效果验证

打包,运行jar包

nohup java -jar springboot-interceptor-and-servletfilter-1.0.jar &

浏览器访问:localhost:8080/

查看服务日志,能看到打印了运程主机和运程地址

三 为Spring Boot项目添加拦截器

Spring Boot拦截器

在Spring Boot中使用拦截器,可在以下情况下执行操作 -

  • 在将请求发送到控制器之前
  • 在将响应发送给客户端之前

例如,使用拦截器在将请求发送到控制器之前添加请求标头,并在将响应发送到客户端之前添加响应标头。

要使用拦截器,需要创建支持它的@Component类,它应该实现HandlerInterceptor接口。
以下是在拦截器上工作时应该了解的三种方法 -

  • preHandle()方法 - 用于在将请求发送到控制器之前执行操作。此方法应返回true,以将响应返回给客户端。
  • postHandle()方法 - 用于在将响应发送到客户端之前执行操作。
  • afterCompletion()方法 - 用于在完成请求和响应后执行操作。

1.在springboot项目 com.practice.demo目录下新建子目录model,用来存放POJO类Product。

Product.java文件内容如下

package com.practice.demo.model;

public class Product {
    private String id;
    private String name;


    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

2.在springboot项目 com.practice.demo目录下新建ProductController类。

ProductController.java的代码如下:

package com.practice.demo;

import com.practice.demo.model.Product;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

@RestController
public class ProductController {
    private static Map<String,Product> productRepo = new HashMap<>();
    static {
        Product apple = new Product();
        apple.setId("1");
        apple.setName("Apple");
        productRepo.put(apple.getId(),apple);
        Product beaf =new Product();
        beaf.setId("2");
        beaf.setName("Beaf");
        productRepo.put(beaf.getId(),beaf);
    }

    @RequestMapping(value = "/products")
    public ResponseEntity<Object> getProduct() {
        return new ResponseEntity<>(productRepo.values(), HttpStatus.OK);
    }
}

此时,该SpringBoot项目已有两个Controller,项目可正常启动,访问控制器。

3. 在springboot项目 com.practice.demo目录下新建interceptor子目录,用来存放拦截器和Spring MVC配置适配器。

a. 创建一个实现了HandlerInterceptor接口的拦截器类,可重写其中的方法,有三个可重写方法: preHaddle、postHandle、afterCompletion

b. 创建一个实现了 WebMvcConfigurer 接口的配置适配器类,并重写 addInterceptors 方法来注册拦截器。在重新的addInterceptors方法中,使用registry.addInterceptor()来添加拦截器,并通过addPathPatterns()来指定要拦截的路径模式,也可以使用excludePathPatterns()排除某些路径。

c.运行应用程序后,拦截器将根据配置的路径模式拦截相应的请求,并执行定义的操作。

ServiceInterceptor.java文件内容如下
package com.practice.demo.interceptor;

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

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 访问任意Controller的时候都会调用该实现类的三个方法
 */
@Component
public class ServiceInterceptor implements HandlerInterceptor {
    // 默认不会重写实现访问

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("PreHaddler method is Calling");
        return true; // 默认return false
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("PostHandle method is Calling");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("Ruquest and Response is completed");
    }
}
ServiceInterceptorConfigAdapter.java文件内容如下:
package com.practice.demo.interceptor;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

//定制 SpringMVC的一些功能都使用WebMvcConfiguer
@Component
public class ServiceInterceptorConfigAdapter implements WebMvcConfigurer {
    //默认不会重写实现方法

    @Autowired
    ServiceInterceptor serviceInterceptor;

    /**
     * 服务启动的时候就会调用该方法
     *
     * @param registry 相当于拦截器的注册中心
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //往注册中心添加拦截器
        registry.addInterceptor(serviceInterceptor).excludePathPatterns();
        System.out.println("往注册中心添加拦截器");
    }
}

4.效果验证

启动项目,发现启动的时候调用了 配置适配器的 addInterceptors方法,而访问 http://localhost:8080/products 和 http://localhost:8080/ 都会调用拦截器里的方法。

参考链接:Springboot——拦截器_springboot 拦截器_我爱布朗熊的博客-CSDN博客

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值