洛江区建设局网站,域名怎么和网站绑定,网站建设耂首先金手指,天津网站建设论坛过滤器#xff0c;监听器与拦截器的区别
过滤器和监听器不是Spring MVC中的组件#xff0c;而是Servlet的组件#xff0c;由Servlet容器来管理。拦截器是Spring MVC中的组件#xff0c;由Spring容器来管理
Servlet过滤器与Spring MVC 拦截器在Web应用中所处的层次如…过滤器监听器与拦截器的区别
过滤器和监听器不是Spring MVC中的组件而是Servlet的组件由Servlet容器来管理。拦截器是Spring MVC中的组件由Spring容器来管理
Servlet过滤器与Spring MVC 拦截器在Web应用中所处的层次如下图所示
过滤器Filter
过滤器是Servlet的高级特性之一是实现Filter接口的Java类。其基本功能就是对Servlet的调用进行干预在Servlet请求和响应的过程中增加一些特定的功能。
应用场景
在过滤器中修改字符编码CharacterEncodingFilter、在过滤器中修改HttpServletRequest的一些参数如过滤低俗文字、危险字符、敏感词过滤、响应信息压缩、控制权限、控制转向、做一些业务逻辑判断等
工作原理
使用Filter完整的流程是Filter对用户请求进行预处理接着将请求交给Servlet进行处理并生成响应最后Filter再对服务器响应进行后处理。 当服务器启动会创建Filter对象并调用init方法只调用一次。 当访问资源路径与Filter的拦截路径匹配会执行Filter中的doFilter方法 当服务器关闭时会调用Filter的destroy方法来进行销毁操作。
Filter接口
通过看Filter接口代码其有三个方法
public interface Filter {default void init(FilterConfig filterConfig) throws ServletException {}void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;default void destroy() {}
}init(FilterConfig conf)方法用于执行过滤器的初始化工作web容器会在web项目启动时自动调用该方法。 doFilter(ServletRequest request,SerlvetResponse responseFilterChain chain)方法当请求和响应被过滤器拦截后都会交给doFilter来处理:其中两个参数分别是被拦截request和response对象可以使用chain的doFliter方法来放行。 destroy()方法用于释放关闭Filter对象打开的资源在web项目关闭时由web容器自动调用该方法。
开发一个Filter
开发一个过滤器比较简单第一步实现Filter接口第二步配置过滤器 实现Filter接口
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseCookie;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Enumeration;Component
WebFilter(filterName myFilter,urlPatterns {/*})
public class MyFilter implements Filter {Overridepublic void init(FilterConfig filterConfig) throws ServletException {//获取filter名字String filterName filterConfig.getFilterName();//获取filter里配置的init-param配置指定参数的值,如果参数不存在则返回 nullString email filterConfig.getInitParameter(email);//获取filter里配置的init-param配置所有参数值,如果过滤器没有初始化参数则返回一个空的 EnumerationEnumerationString initParameterNames filterConfig.getInitParameterNames();//返回对调用者在其中执行操作的 ServletContext 的引用。ServletContext servletContext filterConfig.getServletContext();}Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest httpRequest (HttpServletRequest) servletRequest;HttpServletResponse httpResponse (HttpServletResponse) servletResponse;//统一编码处理httpRequest.setCharacterEncoding(UTF-8);httpResponse.setContentType(text/html;charsetUTF-8);//添加name属性httpRequest.setAttribute(name, tom);//获取请求中的所有cookieCookie[] cookies httpRequest.getCookies();if (cookies ! null) {StringBuilder sb new StringBuilder();for (Cookie cookie : cookies) {String cookieName cookie.getName();String cookieValue cookie.getValue();//设置cookie的相关属性ResponseCookie lastCookie ResponseCookie.from(cookieName, cookieValue).httpOnly(true).sameSite(Lax).build();httpResponse.addHeader(HttpHeaders.SET_COOKIE, lastCookie.toString());}filterChain.doFilter(httpRequest, httpResponse);}}Overridepublic void destroy() {}
}配置Filter 1在web.xml中配置
filterfilter-namemyFilter/filter-namefilter-classcom.lsl.mylsl.filter.MyFilter/filter-classinit-paramparam-nameemail/param-nameparam-value15***011qq.com/param-value/init-param
/filter
filter-mappingfilter-namemyFilter/filter-nameurl-pattern/*/url-pattern
/filter-mappingfilter配置
fliter-name:指为过滤器的名字
filter-class:过滤器的完整类名
init-param:用于为过滤器指定初始化参数它的子元素指定参数的名字
filter-mapping配置
filter-name:你在fliter中声明的filter-name
url-patten:设置 filter 所拦截的请求路径(过滤器关联的URL样式)
2注解配置
WebFilter(filterName myFilter,urlPatterns {/*})3配置类配置
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;Configuration
public class MyFilterConfig {Beanpublic FilterRegistrationBean myFilter(){FilterRegistrationBean fb new FilterRegistrationBean();//设置filter启动顺序fb.setOrder(1);fb.setFilter(new MyFilter());fb.addInitParameter(email,15***11qq.com);//设置拦截请求规则,这里拦截所有请求fb.addUrlPatterns(/*);return fb;}
}三种Filter配置的优缺点 第一种xml的配置需要在xml中写配置但是现在大部分是springboot项目开发都是重注解轻配置现在不怎么使用了。如果xml中配置了多个filter那么按上下先后顺序依次起作用。第二种注解配置写法比较简单但是有一个缺点多个filter没法控制先后顺序。如果想用这个注解但是还想控制filter的先后顺序网上有个说法就是按filter的名字首字母顺序来确定先后顺序比如有多个filter的名字是AdminFilter和UserFilter,那么就是前者先生效后者后生效。第三种配置类配置我个人比较倾向于这个(当然如果就是一个简单filter用注解最简单方便)有xml配置的所有功能。可以定义启动顺序初始化参数等。拦截器Interceptor
Spring MVC中的拦截器( Interceptor)类似于Servlet中的过滤器( Filter )它主要用于拦截用户请求并作出相应的处理。例如通过拦截器可以进行权限验证、记录请求信息的日志、判断用户是否登录等。
工作原理
一个拦截器只有 preHandle 方法返回 true postHandle 、 afterCompletion 才有可能被执行如果 preHandle 方法返回 false 则该拦截器的 postHandle 、 afterCompletion 必然不会被执行。拦截器不是Filter却实现了Filter的功能其原理在于 所有的拦截器 (Interceptor) 和处理器 (Handler) 都注册在 HandlerMapping 中。Spring MVC 中所有的请求都是由 DispatcherServlet 分发的。当请求进入 DispatcherServlet.doDispatch() 时候首先会得到处理该请求的 Handler 即 Controller 中对应的方法以及所有拦截该请求的拦截器。拦截器就是在这里被调用开始工作的。应用场景
拦截器本质上是面向切面编程AOP符合横切关注点的功能都可以放在拦截器中来实现主要的应用场景包括
登录验证判断用户是否登录。权限验证判断用户是否有权限访问资源如校验token日志记录记录请求操作日志用户Ip访问时间等以便统计请求访问量。处理Cookie、本地化、国际化、主题等。性能监控监控请求处理时长等。
拦截器执行顺序 拦截器接口HandlerInterceptor
package org.springframework.web.servlet;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.lang.Nullable;public interface HandlerInterceptor {default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {return true;}default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, Nullable ModelAndView modelAndView) throws Exception {}default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Nullable Exception ex) throws Exception {}
}从代码可以看出拦截器接口有三个方法分别的作用是
preHandle方法叫做预处理方法本方法在控制器方法MyController的方法之前执 行用户的请求最先到达此方法在这个方法中可以获取请求的信息验证请求是否符合要求。以验证用户是否登录验证用户是否有权限访问某个链接地址url。如果返回true则放行返回false则拦截。
postHandle方法叫做后处理方法。在controller中的方法之后执行的。能够获取到处理器方法的返回值 mv可以修改mv中的数据和视图。可以影响到最后的执行结果。主要是对原来的执行结果做二次修正
afterCompletion方法最后执行的方法在页面渲染之后执行。在请求处理完成后执行的框架中规定是当你的视图处理完成后对视图进行了forword。就任务请求处理完成。一般做资源回收工作的程序请求过程中创建了一些对象。在这里可以删除吧占用的内存回收
开发一个拦截器Interceptor
开发一个拦截器需要2步第一步实现HandlerInterceptor接口来定义一个拦截器第二步就是配置拦截器了
1定义一个拦截器
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class MyInterceptor implements HandlerInterceptor {Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {//在拦截的请求了添加属性,在对应请求的controller中的request中就可以获取该参数了//比如String userName (String)request.getAttribute(userName);request.setAttribute(userName,lsl);//获取cookieCookie[] cookies request.getCookies();//设置header属性response.addHeader(SameSite,Lax);//添加cookieCookie cookie new Cookie(name,lsl);response.addCookie(cookie);return true;}Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);}Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {HandlerInterceptor.super.afterCompletion(request, response, handler, ex);}
}2配置拦截器
package com.lsl.mylsl.interceptor;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** 拦截器配置类*/
Configuration
public class MyInterceptorConfig implements WebMvcConfigurer {/*** 配置拦截器* param registry*/Overridepublic void addInterceptors(InterceptorRegistry registry){registry.addInterceptor(myInterceptor()).addPathPatterns(/api/lsl/**)//需要拦截的请求.addPathPatterns(/api/mjx/**)//需要拦截的请求.excludePathPatterns(/api/debug/**)//不拦截的请求.excludePathPatterns(api/lsl/getName);//不拦截的请求}/*** 注入拦截器到spring容器* return*/Beanpublic MyInterceptor myInterceptor(){return new MyInterceptor();}
}过滤器与拦截器工作流程 过滤器和拦截器区别
运行的顺序不同
过滤器是Servlet容器接收到请求后在Servlet被调用之前运行的而拦截器则是在Servlet被调用之后但是在响应发送到客户端之前来运行的
配置方式不同
过滤器是在web.xml里面进行配置的拦截器是在Spring的配置文件中去进行配置
依赖的对象不同
过滤器依赖于Servlet容器而拦截器不依赖与Servlet容器
操作的对象不同
过滤器中只能对request和response进行操作拦截器可以对requestresponsehandlermodelAndViewexecption进行操作相当于拦截器多了对于Spring MVC生态下组件的一个操作能力
通俗理解
1过滤器Filter当你有一堆东西的时候你只希望选择符合你要求的某一些东西。定义这些要求的工具就是过滤器。理解就是一堆字母中取一个B **2拦截器Interceptor**在一个流程正在进行的时候你希望干预它的进展甚至终止它进行这是拦截器做的事情。理解就是一堆字母中干预它通过验证的少点顺便干点别的东西
转发和重定向区别