前言:
学习任何一门知识,都要先了解。
区别:
过滤器:
是在javaweb中,你传入的request、response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的action进行业务逻辑,比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者 struts的action前统一设置字符集,或者去除掉一些非法字符.。
拦截器:
是在面向切面编程的就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法比如动态代理就是拦截器的简单实现,在你调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在你调用方法后打印出字符串,甚至在你抛出异常的时候做业务逻辑的操作。
区分详解:
①拦截器是基于Java的反射机制的,而过滤器是基于函数回调。
②拦截器不依赖于servlet容器,过滤器依赖于servlet容器。
③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
④拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
⑤在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
⑥拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。
了解完,接下来是演示了?(这里使用的是案例演示!)
案例说明:
用户没有登录不能访问主页面,只有用户登录后才可以访问主页。
使用session判断用户是否登录。
拦截器:
首先你要编写一个类,来实现接口HandlerInterceptor。
一共有三个方法可以重写,一般根据需要来重写。
//controlller处理之前方法执行
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
//controller执行完后
```default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable ModelAndView modelAndView) throws Exception {
}
//在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable Exception ex) throws Exception {
}
根据案例这里主要使用第一个方法(preHandle
)
具体代码:
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//获取session
HttpSession session = request.getSession();
//判断是否存在key为user的
if(session.getAttribute("user")!=null){
return true;
}
//否者返回登录
else{
request.getRequestDispatcher("/login.html").forward(request,response);
}
return false;
}
到这里也就完成了一般;
编写拦截器配置文件类并继承 WebMvcConfigurer类,并重写其中的方法 addInterceptors并且在主类上加上注解 @Configuration
@Configuration
public class mvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
InterceptorRegistration registration = registry.addInterceptor(new loginInterceptor());
registration.addPathPatterns("/*");//表示所有请求都被拦截
registration.excludePathPatterns("/css/*"
,"/login.html"
,"/fonts/*"
,"/images/**"
,"/js/**"
,"/lib/**");//表示哪些静态资源不被拦截
}
}
这里也就完成了!测试即可!
过滤器:
有两种方式可以实现过滤器;接下来一一演示。
方式一:
自己定义类实现Filter接口即可
在类上标注注解:
@WebFilter注解,filterName属性表示filter的名称,urlPatter表示要拦截的URL资源,可以是一个或者多个。
@Order(1) 表示如果有多个拦截器的话就是设置这个拦截器的运行等级,数字越小,越先执行
代码演示:
@Order(1)
@WebFilter(filterName = "myFilter",urlPatterns = {"/"})//(细节)urlPatterns:匹配路径可以根据指定访问拦截,例如:“/index”. “/*”表示所有过滤,包括静态资源,会造成页面加载不完全
public class myFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("初始化");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//这里是细节,
HttpServletRequest request=(HttpServletRequest) servletRequest;
HttpSession session = request.getSession();
System.out.println(session.getAttribute("user"));
if(session.getAttribute("user")!=null){
filterChain.doFilter(servletRequest,servletResponse);
}
else{
request.getRequestDispatcher("/login.html").forward(servletRequest,servletResponse);
}
}
@Override
public void destroy() {
System.out.println("销毁");
}
}
(细节)urlPatterns:匹配路径可以根据指定访问拦截,例如:“/index”. “/*”表示所有过滤,包括静态资源,会造成页面加载不完全。
然后在主启动类上加入扫描包注解即可:
@ServletComponentScan("com.lvwenguo.config")
到这里就完成了,测试即可!
方式二:
在配置类实现接口WebMvcConfigurer
类中注入bean的方式:
主启动类的注解可以省略不要;
自己实现类注解省略不要;
public class myFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("初始化");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//这里是细节,
HttpServletRequest request=(HttpServletRequest) servletRequest;
HttpSession session = request.getSession();
System.out.println(session.getAttribute("user"));
if(session.getAttribute("user")!=null){
filterChain.doFilter(servletRequest,servletResponse);
}
else{
request.getRequestDispatcher("/login.html").forward(servletRequest,servletResponse);
}
}
@Override
public void destroy() {
System.out.println("销毁");
}
}
配置实现类:
@Configuration
public class mvcConfig implements WebMvcConfigurer {
@Bean
public FilterRegistrationBean registFilter(){
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new myFilter());//这里还是自己实现类
registrationBean.addUrlPatterns("/");
registrationBean.setName("Filter");
registrationBean.setOrder(1);
return registrationBean;
}
}
细节: 和方法一类似:
总结:
根据案例是理解新知识的快速方式,不是唯一的,但是最有效率。
这里是根据session实现的,根据需要即可添加指定业务即可!