Filter(过滤器)
1、是Sun公司提供的一种特殊的组件,可以对用户的请求进行拦截,执行特定的功能
2、常见的应用:过滤敏感词,访问权限控制,压缩响应内容
1)如何开发一个过滤器
与开发Servlet类似
1、开发一个过滤器类,实现Filter接口
2、重写Filter接口中定义的3个抽象方法
-
1.
init(FilterConfig fConfig)
- 1.fConfig中封装的是在web.xml中为该Filter配置的初始化参数
- 2.开发者仅需要调用fConfig的api,就可以读取配置的参数
-
2.
destory(request,response,chain)
chain.doFilter(request, response);
-
3.
doFilter(ServletRequest request, ServletResponse response, FilterChain chain){}
:添加过滤器生效的逻辑 -
4.Servlet中的doGet/doPost方法的参数与Filter的doFilter方法的参数:
doPost(HttpServletRequest request, HttpServletResponse response)
doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
- ServletRequest和HttpServletRequest的关系
- 1.HttpServletRequest继承了ServletRequest
- 2.HttpServletRequest额外添加了一些处理http协议相关方法
- 1.request.getMethod(); //获取用户的请求方式(7种,http)
- 2.request.getSession();
- 3.HttpServletResponse继承了ServletResponse,添加了http协议相关的方法
- 1.response.sendRedirect(); //重定向
3、在web.xml中配置一个Filter
<filter>
<filter-name></filter-name>
<filter-class></filter-class>
</filter>
<filter-mapping>
<filter-name></filter-name>
<url-pattern>过滤器所拦截的url</url-pattern>
</filter-mapping>
2)一个Filter拦截多个请求
1、新添加一组<filter-mapping></filter-mapping>
标签
2、使用*
作为通配符
<url-pattern>/*</url-pattern>
拦截所有请求<url-pattern>/user/*</url-pattern>
拦截所有/user目录下的请求
3)多个过滤器配合使用
1、多个Filter生效的顺序由<filter-mapping>
标签在web.xml中出现的顺序来决定
2、<filter-mapping>
标签越靠前,Filter越优先生效
4)拦截不同方式的访问请求
1、在web.xml文件中,一个<filter-mapping>
元素用于配置一个Filter所负责拦截的资源。 <filter-mapping>
元素中有一个特殊的子元素<dispatcher>
,该元素用于指定过滤器所拦截的资源被Servlet容器调用的方式。
例如:
<filter-mapping>
<filter-name>CharacterFilter</filter-name>
<url-pattern>/Servlet09</url-pattern>
<dispatcher>FORWAORD</dispatcher>
</filter-mapping>
2、<dispatcher>
元素的值共有4个:
1)REQUEST :当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器将不会被调用。
2)INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
3)FORWARD :如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
4)ERROR :如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。
5)Filter的生命周期
1、分为4个阶段︰创建、初始化、服务、销毁
2、创建: 服务器启动,即加载和实例化所有的Filter
3、初始化: 在实例化之后,马上调用Filter的init()方法,执行初始化的逻辑(由开发者来提供)
4、服务: 每当有请求和该Filter拦截的url一致时,服务器会调用该Filter的doFilter()方法,对请求进行拦截,该方法在整个生命周期中会被调用多次
5、销毁: 当服务器关闭或者当前web应用被移出容器时,Filter会被销毁,销毁前服务器会调用它的destory()方法,执行销毁的逻辑(由开发者提供)
6、Servlet和Filter在整个项目运行阶段,都只有一个实例,不同请求是基于多线程访问同一个实例
5)实现Emp权限访问控制
①
- 1.配置web.xml中的路径
- 2.配置各个.jsp文件的路径。
- 1.默认情况.jsp文件的href路径和src路径为相对路径,但是在添加“/admin”权限访问控制后,使用相对路径会出现JSP页面404错误。所以应改为绝对路径。
- 可以利用html提供的base标签解决这一问题。以下操作在
<head>
标签中实现
<%String path=request.getContextPath();
//动态生成basePath,后期路径变化,代码不用修改
String bsePath=request.getScheme()+"://"
+request.getServerName()+":"
+request.getServerPort( )+path+"/";
%>
<!-- 用于指定当前页面的父路径,供拼接路径使用 -->
<!-- 格式href="协议://域名:端口号/项目路径/" -->
<base href="<%=basePath %>">
②
LoginServlet:
//向Session中添加用户登录状态
HttpSession session = request.getSession();
session.setAttribute("user", username);
LoginFilter:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {
//HttpservletRequest继承了ServletRequest
//HttpServletRequest额外添加了一些处理http协议相关方法,如:
//1.request.getMethod(); //获取用户的请求方式(7种,http)
//2.request.getSession();
//通过session判断用户是否有登录状态,应强转request类型为HttpServletRequest
HttpServletRequest req = (HttpServletRequest)request;
HttpSession session = req.getSession();
//判断用户是否有登录状态
if(session==null || session.getAttribute("user")==null) {
//无则将请求重定向到登录页面
((HttpServletResponse)response).sendRedirect(req.getContextPath()+"/login.jsp");
}else {
//有则放行
chain.doFilter(request, response);
}
}