- 【复习】过滤器(Filter)
过滤器是Java EE中的组件。
过滤器是执行在Servlet之前的组件。
过滤器可以对请求进行过滤,如果不满足自行指定的条件,可以拦截下来,不予放行,请求就不会被Servlet处理。
过滤器也需要在web.xml中配置注册,通常,映射的路径范围较大,因为它通常用于处理多个甚至所有Servlet需要执行的任务。
同一个应用中可以存在多个过滤器,形成“过滤器链”,当某个请求被服务器处理时,会依次执行各个过滤器,只有全部放行,才会被Servlet处理。
过滤器的配置与Servlet非常相似:
<filter>
<filter-name></filter-name>
<filter-class></filter-class>
</filter>
<filter-mapping>
<filter-name></filter-name>
<url-pattern></url-pattern>
</filter-mapping>
//拦截器我自己认为更像是if else的升级版本
//将大量的不想让被访问的请求过滤拦截调
//其实就比如就让登录注册这样的请求能够获得访问,其它的请求都不能获得访问
//只能通过登录注册才能进行到其他的访问才可以这样很好的将拦截器使用的妥当
- SpringMVC中的拦截器(Interceptor)
2.1. 基本概念
SpringMVC中的拦截器的作用与过滤器非常相似,也是可以设置为诸多请求都会执行的组件,它执行时,优先于控制器(其实,每个拦截器都会执行3次,1次在控制器之前,2次在控制器之后,通常关注的是在控制器之前执行的那一次)。
2.2. 基本使用
自定义拦截器需要实现HandlerInterceptor接口,该接口中共3个抽象方法,其中,preHandle()方法是在控制器之前执行的,可以起到拦截效果,该方法的返回值表示是否拦截,为true时放行,为false时拦截。
public class LoginInterceptor implements HandlerInterceptor {
public boolean preHandle(
HttpServletRequest request,
HttpServletResponse response,
Object handler)
throws Exception {
// 测试输出
System.out.println("LoginInterceptor.preHandle()");
// 拦截规则:
// 如果未登录,重定向到登录,并拦截
// 如果已登录,直接放行
HttpSession session = request.getSession();
if (session.getAttribute("username") == null) {
response.sendRedirect("../user/login.do");
return false;
}
// 返回:true=放行,false=拦截
return true;
}
// ... 其它代码...
}
所有拦截器还必须在Spring的配置文件中进行配置:
<!-- 拦截器链 -->
<mvc:interceptors>
<!-- 第1个拦截器 -->
<mvc:interceptor>
<!-- 1. 黑名单 -->
<mvc:mapping path="/user/*"/>
<!-- 2. 白名单 -->
<mvc:exclude-mapping path="/user/reg.do"/>
<mvc:exclude-mapping path="/user/login.do"/>
<mvc:exclude-mapping path="/user/handle_reg.do"/>
<mvc:exclude-mapping path="/user/handle_login.do"/>
<!-- 3. 拦截器类 -->
<bean class="cn.tedu.spring.LoginInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
在配置时,可以使用星号*作为通配符,但是,它只能匹配1级路径,例如:/user/可以通配/user/reg.do、/user/login.do等,却无法匹配/user/a/list.do!如果需要表示多级路径中的通配,则需要使用2个星号*!
3. 处理请求参数的乱码问题
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
package cn.tedu.store.configurer;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import cn.tedu.store.interceptor.LoginInterceptor;
@Configuration
public class WebAppConfigurer
implements WebMvcConfigurer {
@Override
public void addInterceptors(
InterceptorRegistry registry) {
// 黑名单
List<String> pathPatterns
= new ArrayList<>();
pathPatterns.add("/user/**");
pathPatterns.add("/web/**");
pathPatterns.add("/address/**");
//拦截器我自己认为更像是if else的升级版本
//将大量的不想让被访问的请求过滤拦截调
//其实就比如就让登录注册这样的请求能够获得访问,其它的请求都不能获得访问
//只能通过登录注册才能进行到其他的访问才可以这样很好的将拦截器使用的妥当
// 白名单
List<String> excludePathPatterns
= new ArrayList<>();
excludePathPatterns.add("/user/reg.do");
excludePathPatterns.add("/user/login.do");
excludePathPatterns.add("/web/register.html");
excludePathPatterns.add("/web/login.html");
// 注册
registry.addInterceptor(new LoginInterceptor()).addPathPatterns(pathPatterns)
.excludePathPatterns(excludePathPatterns);
}
}插入代码片
package cn.tedu.store.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.servlet.HandlerInterceptor;
/**
* 登录拦截器
*/
public class LoginInterceptor
implements HandlerInterceptor {
@Override
public boolean preHandle(
HttpServletRequest request,
HttpServletResponse response,
Object handler)
throws Exception {
// 获取Session对象
HttpSession session
= request.getSession();
// 判断Session中是否存在uid
if (session.getAttribute("uid") == null) {
// 为null,即没有uid,即没有登录
response.sendRedirect("../web/login.html");
// 拦截
return false;
} else {
// 非null,即存在uid,即已经登录
return true;
}
}
}