Filter 过滤器的使用
【1】什么是Filter(过滤器)?
[2]怎么使用Filter ?
(1)实现Filter 的接口(javax.servlet.Filter;)重写其中的 doFilter() 方法。
(2)在web.xml配置Filter 的参数。
<!-- 配置过滤器 -->
<filter>
<filter-name>MyFilter</filter-name>
<filter-class>filter.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
【3】Filter 的生命周期
package filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class MyFilter implements Filter {
//创建过滤器对象后,立即执行本方法(当web 程序加载的时候调用,只执行一次)
public void init(FilterConfig arg0) throws ServletException {
System.out.println("init()....");
}
//拦截用户的请求,如果请求资源路径和当前过滤器的拦截路径匹配时,就执行本方法
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
System.out.println("request 被处理之前...");
//放行(将请求交给下一个过滤器或者交给目标资源)
chain.doFilter(req, res);
System.out.println("request 被处理之后,response 抵达客户端浏览器之前...");
}
//过滤器对象销毁前执行,
(当web 程序卸载的时候调用,只执行一次)public void destroy() {
System.out.println("destory....");
}
- }
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("myServlet....");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//通过请求转发得到目标资源
request.getRequestDispatcher("/index.jsp").forward(request, response);
}
Filter 执行输出语句到页面
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
res.getWriter().print("myFilter...");
}
<filter>
<filter-name>MyFilter</filter-name>
<filter-class>filter.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/index.jsp</url-pattern>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
【4】处理多个Filter ,执行的先后次序
<!-- 配置MyFilter01 -->
<filter>
<filter-name>MyFilter01</filter-name>
<filter-class>filter.MyFilter01</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter01</filter-name>
<url-pattern>/MyServlet</url-pattern>
</filter-mapping>
<!-- 配置MyFilter02 -->
<filter>
<filter-name>MyFilter02</filter-name>
<filter-class>filter.MyFilter02</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter02</filter-name>
<url-pattern>/MyServlet</url-pattern>
</filter-mapping>
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
PrintWriter out = res.getWriter();
out.print("myFilter01...");
//放行
chain.doFilter(req, res);
out.print("myFilter01 back...");
}
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
PrintWriter out = res.getWriter();
out.print("myFilter02...");
//放行
chain.doFilter(req, res);
out.print("myFilter02 back...");
}
【5】拿取Filter 中配置文件的初始化参数信息
FilterConfig接口
为了获取Filter程序在web.xml文件中的配置信息,Servlet API提供了一个FilterConfig接口,该接口封装了Filter程序在web.xml中的所有注册信息,并且提供了一系列获取这些配置信息的方法。
<filter>
<filter-name>MyFilter</filter-name>
<filter-class>filter.MyFilter</filter-class>
<!-- 初始化参数配置 -->
<init-param>
<param-name>school</param-name>
<param-value>rjxy</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/MyServlet</url-pattern>
</filter-mapping>
<filter>
<filter-name>myFilter01</filter-name>
<filter-class>filter.Filter01</filter-class>
<init-param>
<param-name>name</param-name>
<param-value>耿帅佳</param-value>
</init-param>
</filter>
package filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class MyFilter implements Filter {
public void destroy() {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain arg2) throws IOException, ServletException {
// TODO Auto-generated method stub
}
public void init(FilterConfig config) throws ServletException {
// 获取过滤器名字
String name = config.getFilterName();
System.out.println(name);
//获取SerletContext对象
ServletContext sc = config.getServletContext();
System.out.println(sc);
//获取初始化参数根据参数名
String value = config.getInitParameter("school");
System.out.println(value);
}
}
【6】常见的Filter - 字符编码
在Web开发中,经常会遇到中文乱码问题,现在,我们可以在Filter中对获取到的请求和响应消息进行编码,从而统一全站的编码方式。
那么我们处理的就是 get 或者 post 请求发生的中文乱码情况。
那我们的思路应该是:
(1)用户请求 (get 或者 post 方式)
(2)先走Filter 中,判断是 get 还是 post 请求方式,获取用户的请求的数据,并根据不同的请求方式来处理中文乱码。
(3)然后走 Servlet 方法就完成了。
************************************************
Filter过滤器可以获取到代表用户请求和响应的request、response对象。可是如果想对request和response对象中的任何信息进行修改,则需要通过包装类来实现。
在Servlet API中,提供了HttpServletRequestWrapper和HttpServletResponseWrapper两个类,它们分别是request和response对象的包装类。
***************************************************
package filter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
/**
* 字符过滤器处理中文乱码
* @author Administrator
*
*/
public class CharacterFilter implements Filter {
public void destroy() {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)res;
//拦截请求处理乱码
//post请求
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
/*
* 对request进行包装
* characterRequest功能增强了,获取中文参数直接处理乱码
*/
CharacterRequest characterRequest = new CharacterRequest(request);
//放行
chain.doFilter(characterRequest, response);
}
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
//对request对象重新包装(增强的功能:处理get请求的中文乱码)
class CharacterRequest extends HttpServletRequestWrapper{
public CharacterRequest(HttpServletRequest request) {
super(request);
// TODO Auto-generated constructor stub
}
/*
* 重写getParameter(),增强的功能:处理get请求的中文乱码
*/
public String getParameter(String name){
//调用被包装对象已有的方法,获取请求参数
String value = super.getParameter(name);
if(value == null){
return null;
}
//判断请求方式
String method = super.getMethod();
//如果是get请求
if("get".equalsIgnoreCase(method)){
try {
value = new String(value.getBytes("ISO-8859-1"),"UTF-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return value;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- 配置字符过滤器 -->
<filter>
<filter-name>CharacterFilter</filter-name>
<filter-class>filter.CharacterFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>CharacterServlet</servlet-name>
<servlet-class>servlet.CharacterServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CharacterServlet</servlet-name>
<url-pattern>/CharacterServlet</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
特别注意:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="ISO-8859-1" />