过滤器
FilterConfig接口
该接口类型作为 Filter 接口中的 init 方法的参数使用, FilterConfig接口中有一个常用方法
getInitParameter(String name) , 该 方 法 用 来 获 得 过 滤 器 的 初 始 化 参 数 值 。 在 web.xml中,可以为每一个 filter配置需要的初始化参数,与 Servlet 的 <init-param> 类似。过滤器的初始化参数即可通过FilterConfig中的getInitParameter方法获取。
过滤器可以解决这个问题,可以用来进行通用处理,而不 需要在多个文件中写相同代码。
什么是过滤器
过滤器是在数据交互之间过滤数据的中间组件,独立于任 何平台或者 Servlet 容器。
过滤器可以应用在客户机和 servlet 之间、 servlet 和 servlet 或 JSP 页面之间,以及所包括的每 个 JSP 页面之间。
使用初始化参数
获得初始化参数后,可以在需要的时候使用。例如,在 doFilter方法中,根据当前时间判断是否需要访问控制。
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { Timestamp now=new Timestamp(System.currentTimeMillis()); int nowhour=now.getHours(); if(nowhour>start&&nowhour<end){ HttpServletRequest request=(HttpServletRequest)arg0; HttpSession session=request.getSession(); String username=(String) session.getAttribute("username"); if(username==null){ request.getRequestDispatcher("../index.jsp").forward(arg0, arg1); } } arg2.doFilter(arg0, arg1); }
当服务器启动,会创建Filter对象,并调用init方法,只 调用一次. 当访问资源时,路径与 Filter 的拦截路径匹配,会执行 Filter中的doFilter方法,这个方法是真正拦截操作的方 法. 当服务器关闭时,会调用Filter 的destroy 方法来进行销 毁操作.
思考:没有过滤如何实现?
过滤器在Web开发中的一些主要应用:
过滤器是通常封装了一些功能的 Web 组件,这些功能虽 然很重要,但是对于处理客户机请求或发送响应来说不是 决定性的。
对用户请求进行统一认证。 对用户的访问请求进行记录和审核。 对用户发送的数据进行过滤或替换。 转换图象格式。 对响应内容进行压缩,减少传输量。 对请求或响应进行加解密处理 触发资源访问是事件。
实现过滤器分为三步
1、编写过滤器实现类。
2、配置过滤器。把该过滤器添加到 Web 应用程序中(通 过在 Web 部署描述符 /web.xml 中声明它);
3 、部署过滤器。把过滤器与应用程序一起打包并部署 它;
filter生命周期
Servlet生命周期:
实例化 --》 初始化 --》 服务 --》 销毁Fra bibliotek运行效果
直接访问 admin 下的任意 JSP ,都将跳转到 index.jsp ,提 示需要登录。
登录后,可以访问admin下的任意JSP
登录后可以访问 直接访问admin下JSP,将跳转 到index.jsp
配置过滤器初始化参数
和 Servlet类似,过滤器也可以配置初始化参数,过滤器 的初始化参数,只能在当前过滤器中使用
注意:参数arg0,arg1是ServletRequest,ServletResponse类 型,常常需要转换成 HttpServletRequest,HttpServletResponse类型。 FilterChain的doFilter方法总被调用,用来把请求和响应按照 过滤链传递下去,过滤链由若干个过滤器以及最终的目标资源 组成。
public class LoginFilter implements Filter { private int start; private int end; public void init(FilterConfig arg0) throws ServletException { start=Integer.parseInt(arg0.getInitParameter("start")); end=Integer.parseInt(arg0.getInitParameter("end")); }
过滤器
过滤器的作用
回忆之前访问控制例子
在bbs项目中的页面,访问之前必须登录 实际应用中,一个应用下会有很多页面需要访问控制 目前的实现方案中,需要在每一个需要访问控制的文件中加上判断代码,代 码将很冗余,如果需要修改,也比较繁琐
除了访问控制这样的功能外,Web应用中还会有其他这种 需求,例如权限校验、加密处理等。都需要在若干个文件 中编写类似的代码。
在LoginFilter中配置了两个初始化参数,用来表示需要 访问控制的时间段是凌晨2-6点,其他时间不需要
如何获得初始化参数
过 滤 器 的 初 始 化 参 数 , 使 用 FilterConfig 接 口 的 getInitParameter方法获得。FilterConfig对象是过滤器 类init方法的参数,因此,往往在过滤器类的init方法中 获得过滤器参数。
<filter-name>:与<filter>中的<filter-name>相同 <url-pattern>:该过滤器要过滤的资源的URL,例如/admin/*,即访问admin目录下任意资源都先被该 过滤器过滤 <dispatcher> : 可 以 配 置 四 个 值 , 用 来 指 定 用 哪 种 方 式 访 问 该 资 源 时 才 被 过 滤 。 可以取的值有 REQUEST FORWARD ERROR INCLUDE 它的作用是:当以什么方式去访问web资源时,进行拦截操作. • 1.REQUEST 当是从浏览器直接访问资源,或是重定向到某个资源时进行拦截方式配置的 它也是 默认值 • 2.FORWARD 它描述的是请求转发的拦截方式配置 • 3.ERROR 如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外, 过滤器不会被调用。 • 4.INCLUDE 如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调 用。除此之外,该过滤器不会被调用
如果不用过滤器,如何实现目前的功能?
如果不用过滤器,需要在所有 JSP中都加入相同的验证代 码,如下所示。
<% User users=(User)session.getAttribute("user"); if(users==null){ request.getRequestDispatcher("login.jsp").forward(request,response); } %>
步骤3:配置过滤器
过 滤 器 要 生 效 , 必 须 在 web.xml 中 配 置 , 主 要 配 置 <filter>以及<filter-mapping>
<filter> <filter-name>LoginFilter</filter-name> <filter-class>com.chinasofti.ch10.filter.LoginFilter</filter-class> </filter> <filter-mapping> <filter-name>LoginFilter</filter-name> <url-pattern>/admin/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> <dispatcher>INCLUDE</dispatcher> <dispatcher>ERROR</dispatcher> </filter-mapping>
<filter> <filter-name>LoginFilter</filter-name> <filter-class>com.chinasofti.filter.LoginFilter</filter-class> <init-param> <param-name>start</param-name> <param-value>2</param-value> </init-param> <init-param> <param-name>end</param-name> <param-value>6</param-value> </init-param> </filter>