javaweb中的filter

来源:互联网 发布:淘宝和阿里巴巴哪个好 编辑:程序博客网 时间:2024/05/20 10:15

在现实项目中,很多地方都要用到过滤器,比如处理编码集啊,登录检测啊,缓存啊,都是会用到,过滤器也给我们带来很大的方便。下面我就大概说说过滤器filter

1. Filter 是什么 ?
①. JavaWEB 的一个重要组件, 可以对发送到 Servlet 的请求进行拦截, 并对响应也进行拦截. 
②. Filter 是实现了 Filter 接口的 Java 类.
③. Filter 需要在 web.xml 文件中进行配置和映射. 


2. 如何创建一个 Filter, 并把他运行
①. 创建一个 Filter 类: 实现 Filter 接口: public class HelloFilter implements Filter
②. 在 web.xml 文件中配置并映射该 Filter. 其中 url-pattern 指定该 Filter 可以拦截哪些资源, 即可以通过哪些 url 访问到该 Filter
<!-- 注册 Filter -->
<filter>
<filter-name>helloFilter</filter-name>
<filter-class>com.ymfwj.filter.HelloFilter</filter-class>
</filter>

<!-- 映射 Filter -->
<filter-mapping>
<filter-name>helloFilter</filter-name>
<url-pattern>/test.jsp</url-pattern>
</filter-mapping>

3. Filter 相关的 API:
①. Filter 接口:
> public void init(FilterConfig filterConfig): 类似于 Servlet 的 init 方法. 在创建 Filter 对象(Filter 对象在 Servlet 容器加载当前 WEB 应用时即被创建)后, 立即被调用, 且只被调用一次. 该方法用于对当前的 Filter 进行初始化操作. Filter 实例是单例的. 

*  FilterConfig 类似于 ServletConfig

* 可以在 web.xml 文件中配置当前 Filter 的初始化参数. 配置方式也和 Servlet 类似。

<filter>
<filter-name>helloFilter</filter-name>
<filter-class>com.ymfwj.filter.HelloFilter</filter-class>
<init-param>
<param-name>name</param-name>
<param-value>root</param-value>
</init-param>
</filter>


> public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain): 真正 Filter 的逻辑代码需要编写在该方法中. 每次拦截都会调用该方法. 

* FilterChain: Filter 链. 多个 Filter 可以构成一个 Filter 链.

- doFilter(ServletRequest request, ServletResponse response): 把请求传给 Filter 链的下一个 Filter,
若当前 Filter 是 Filter 链的最后一个 Filter, 将把请求给到目标 Serlvet(或 JSP)

- 多个 Filter 拦截的顺序和 <filter-mapping> 配置的顺序有关, 靠前的先被调用. 

> public void destroy(): 释放当前 Filter 所占用的资源的方法. 在 Filter 被销毁之前被调用, 且只被调用一次. 

4. <dispatcher> 元素: 指定过滤器所拦截的资源被 Servlet 容器调用的方式,
可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默认REQUEST. 
可以设置多个<dispatcher> 子元素用来指定 Filter 对资源的多种调用方式进行拦截

①. REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。

通过 GET 或 POST 请求直接访问。 

②. FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。

或 <jsp:forward page="/..." /> 或 通过 page 指令的 errorPage 转发页面. <%@ page errorPage="test.jsp" %>

②. INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。

或 <jsp:include file="/..." />

④. ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。

在 web.xml 文件中通过 error-page 节点进行声明:

<error-page>
<exception-type>java.lang.ArithmeticException</exception-type>
<location>/test.jsp</location>
</error-page>

<filter-mapping>
<filter-name>secondFilter</filter-name>
<url-pattern>/test.jsp</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>

我就讲讲字符编码的过滤

在WebContent下建一个文件夹encoding,然后在里面写两个jsp

a.jsp:

<body>
<form action="b.jsp" method="post">
用户名:<input type="text" name="name"/>
<input type="submit" value="提交"/>
</form>
</body>

b.jsp:

<body>
Hello:${param.name }
</body>

然后运行:


用户名用中文:


结果乱码了,如下图


要是没有不用过滤器的话直接在b.jsp中把请求设置编码

<%
request.setCharacterEncoding("utf-8");
%>

结果如下,没有乱码:


如果我们用这个方法的话,有很多界面的时候咋办,是吧,下面我们用过滤器来处理

我们编写一个EncodingFilter

1.先读取web.xml文件中配置的当前WEB应用的初始化参数encoding

 <context-param>
  <param-name>encoding</param-name>
  <param-value>utf-8</param-value>
  </context-param>

2.指定请求的字符编码为1中读取到的编码

3.调用chain.doFilter()方法放行请求

public class EncodingFilter implements Filter{
String encoding;
@Override
public void destroy() {}


@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
request.setCharacterEncoding(encoding);
filterChain.doFilter(request, response);

}

FilterConfig filterConfig;
@Override
public void init(FilterConfig config) throws ServletException {
this.filterConfig=config;
encoding=filterConfig.getServletContext().getInitParameter("encoding");
}
}

最后测试是有用的






0 0