Spring boot 集成 servlet、监听器、过滤器、拦截器

Spring boot 集成 servlet

Web 开发使用 Controller 基本上可以完成大部分需求,但是我们还可能会用到 Servlet、Filter、Listener、Interceptor 等等。
当使用 Spring-Boot 时,嵌入式 Servlet 容器通过扫描注解的方式注册 Servlet、Filter 和 Servlet 规范的所有监听器(如HttpSessionListener 监听器)。
Spring boot 的主 Servlet 为 DispatcherServlet,其默认的 url-pattern 为“/”。也许我们在应用中还需要定义更多 的 Servlet,该如何使用SpringBoot 来完成呢?

在 spring boot 中添加自己的 Servlet 有两种方法,代码注册 Servlet 和注解自动注册(Filter 和 Listener 也是如此)。
一、代码注册通过 ServletRegistrationBean、 FilterRegistrationBean 和 ServletListenerRegistrationBean 获得
控制。也可以通过实现 ServletContextInitializer 接口直接注册。
二、在 SpringBootApplication 上使用@ServletComponentScan 注解后,Servlet、Filter、Listener 可以直接通 过 @WebServlet、@WebFilter、@WebListener 注解自动注册,无需其他代码。

maven依赖

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

方式一、代码注册

1、创建一个MyServlet2 类,继承HttpServlet ,重写doGet方法

public class MyServlet2 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("myservlet2正在运行。。。。。。。。");
        resp.setContentType("text/html;charset=utf-8");
        resp.setCharacterEncoding("UTF-8");
        PrintWriter out = resp.getWriter();
        out.println("<html>");
        out.println("<head>");
        out.println("<title>Hello World</title>");
        out.println("</head>");
        out.println("<body>");
        out.println("<h1>这是:MyServlet2</h1>");
        out.println("</body>");
        out.println("</html>");
    }
}

2、在启动类中是实例化ServletRegistrationBean并注入自定义的servlet

public class ServletApplication {

    @Bean
    public ServletRegistrationBean registerMyServlet(){
       return new ServletRegistrationBean(new MyServlet2(),"/myservlet2/*");
    }

    public static void main(String[] args) {
        SpringApplication.run(ServletApplication.class,args);
    }
}

方式二、注解注册

1、创建一个MyServlet1 类,继承HttpServlet ,重写doGet方法,并使用@WebServlet注解,填写访问路径,和servlet名称

@WebServlet(urlPatterns = "/myservlet1/*",name = "myservlet1")
public class MyServlet1 extends HttpServlet {

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        System.out.println("myservlet1正在运行。。。。。。。。");
        resp.setContentType("text/html;charset=utf-8");
        resp.setCharacterEncoding("UTF-8");
        PrintWriter out = resp.getWriter();
        out.println("<html>");
        out.println("<head>");
        out.println("<title>Hello World</title>");
        out.println("</head>");
        out.println("<body>");
        out.println("<h1>这是:MyServlet1</h1>");
        out.println("</body>");
        out.println("</html>");

    }

}

2、使用@ServletComponentScan注解自动注册

@SpringBootApplication
@ServletComponentScan
public class ServletApplication {

    @Bean
    public ServletRegistrationBean registerMyServlet(){
       return new ServletRegistrationBean(new MyServlet2(),"/myservlet2/*");
    }

    public static void main(String[] args) {
        SpringApplication.run(ServletApplication.class,args);
    }
}

Spring boot 集成 Fliter 和 Linstener

过滤器(Filter)和监听器(Listener)的注册方法和 Servlet 一 样;
下面将直接使用@WebFilter 和@WebListener 的方式,完成一个Filter 和一个 Listener;使用注解@ServletComponentScan//这个就是扫描相应的 Servlet 包;

监听器

import lombok.extern.slf4j.Slf4j;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

@Slf4j
@WebListener
public class MyListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        log.info("监听器:listener=====>contextInitialized");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        log.info("监听器:listener=====>contextDestroyed");
    }
}

过滤器

import lombok.extern.slf4j.Slf4j;

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

/**
 * 过滤器是要什么,拦截器是不要什么
 */
@Slf4j
@WebFilter(urlPatterns = "/*",filterName = "myFilter")
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) {
        log.info("过滤器:filter=====>init");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("过滤器:filter=====>doFilter");
        log.info("过滤器:filter=====>before filter");
        filterChain.doFilter(servletRequest,servletResponse);
        log.info("过滤器:filter=====>after filter");
    }

    @Override
    public void destroy() {
        log.info("过滤器:filter=====>destroy");
    }
}

打印结果:
在这里插入图片描述
以上可见,监听器执行初始化,之后进行过滤器的初始化,然后执行过滤器的filterChain.doFilter,再执行servlet方法

Spring boot 拦截器 HandlerInterceptor

过滤器属于 Servlet 范畴的 API,与 Spring 没什么关系。
Web 开发中,我们除了使用 Filter 来过滤请 web 求外,还可以使用 Spring 提供的 HandlerInterceptor(拦 截器)。
HandlerInterceptor 的功能跟过滤器类似,但是提供更精细的的控制能力:在 request 被响应之前request 被响
应之后
视图渲染之前以及 request 全部结束之后。我们不能通过拦截器修改 request 内容,但是可以通过抛出
异常(或者返回 false)来暂停 request 的执行。(意思是:不能修改request内容,但是可以获取request内容后进行判断是否需要停止此次request的执行)
实现 UserRoleAuthorizationInterceptor 的拦截器有:
ConversionServiceExposingInterceptor
CorsInterceptor
LocaleChangeInterceptor
PathExposingHandlerInterceptor
ResourceUrlProviderExposingInterceptor
ThemeChangeInterceptor
UriTemplateVariablesHandlerInterceptor
UserRoleAuthorizationInterceptor
其中 LocaleChangeInterceptor 和 ThemeChangeInterceptor 比较常用。

配 置 拦 截 器 也很简单, Spring 为什么提供了 基 础 类 WebMvcConfigurerAdapter ,我们 只 需 要 重 写
addInterceptors 方法添加注册拦截器。 实现自定义拦截器只需要 3 步:
1、创建我们自己的拦截器类并实现 HandlerInterceptor 接口。
2、创建一个 Java 类继承 WebMvcConfigurer,并重写 addInterceptors 方法。实例化我们自定义的拦截器,然后将对像手动添加到拦截器链中(在 addInterceptors 方法中添加)
3、创建controller类进行测试

拦截器

1、创建一个MyInterceptor自定义类

import lombok.extern.slf4j.Slf4j;
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;


@Slf4j
@Component
public class MyInterceptor implements HandlerInterceptor {

    /**
     * 在将请求发送到控制器controller之前执行操作,若返回true就进入控制器,若返回false就不进入控制器了。
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("拦截器======》preHandle");
        return true;
    }

    /**
     * 用于在将响应发送到客户端之前执行操作,就是控制器执行完之后返回数据时执行。
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("拦截器======》postHandle");
    }

    /**
     * 在完成请求和响应后执行操作。
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("拦截器======》afterCompletion");
    }
}

2、创建WebMvcConfigurer接口的实现类,重写addInterceptors方法

import com.lcj.interceptor.MyInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.annotation.Resource;

@Configuration
public class MyWebMvcConfig implements WebMvcConfigurer {
    //引入自定义拦截器对象
    @Resource
    private MyInterceptor myInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //addInterceptor方法向拦截器注册器添加拦截器,addPathPatterns方法添加拦截路径匹配规则("/**"是拦截所有),excludePathPatterns方法是设置白名单,放行哪些路径
        // 对于order的顺序:拦截器的preHandle方法是顺序执行,
        registry.addInterceptor(myInterceptor).addPathPatterns("/**");
    }
}

3、创建controller类测试

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RestController
@RequestMapping
public class MyController {

    @RequestMapping("/test")
    public String test(){

    log.info("进入=====》test");

    return "你成功啦";
    }
}

测试结果:
在这里插入图片描述
总结:拦截器和过滤器是不同的,
1、一个是spring提供的,一个是servlet的范畴的API,
2、拦截器只能作用于controller层,而过滤器可以过来所有客户端发送过来的请求,包括使用原生servlet方式。
3、拦截器不能修改request中的内容,但是可以获取request中的参数进行判断时候需要停止此次的request请求,主要是对request请求内容的拦截预判断,过滤器主要是针对请求的路径进行过滤,判断这个请求能否通过

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值