2020-12-06 Java Web 过滤器

Java Web 过滤器

什么是过滤器(Filter)

过滤器:任何实现了Filter接口的类称为过滤器类。
实际上就是对web资源进行拦截,做一些处理后再交给下一个过滤器或servlet处理
通常都是用来拦截request进行处理的,也可以对返回的response进行拦截处理

应用场景

  1. 统一设置编码格式
  2. 访问权限控制
  3. 敏感字符过滤等(并未尝试)

思维导图

2020-12-06  Java Web 过滤器
注:在Filter中只有执行 chain.dofilter(request,response) 才算一个过滤,也只有执行此代码后才会进行放行以执行dofilter()以后的代码。

创建Filter

下面我们来创建一个Filter类。

1. 创建一个类

2020-12-06  Java Web 过滤器
包名和类名
2020-12-06  Java Web 过滤器

2. 实现接口Filter

2020-12-06  Java Web 过滤器

3. 鼠标悬浮在类名上,点击Add unimplemented methods

2020-12-06  Java Web 过滤器
自动生成三个方法

public class CharacterEncodedFilter implements Filter {

	public void init(FilterConfig filterConfig) throws ServletException {
		
	}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		
	}

	public void destroy() {
		
	}
	
}

我们需要用到doFilter()方法。

4. 在web.xml中配置Filter

  <filter>
  	<filter-name>web.xml中的名称(两个要像同)比如这里为:ABC</filter-name>
  	<filter-class>Filter类全限定类名</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>web.xml中的名称(两个要像同)那么这里也为:ABC</filter-name>
  	<url-pattern>/register</url-pattern>
  </filter-mapping>

Filter接口中doFilter方法

doFilter方法最为关键,它有三个参数:
参数1 : ServletRequest request
参数2 : ServletResponse response
参数3 : FilterChain chain 过滤器链

过滤器对象由容器来实例化, 当有请求请求该过滤器时,容器会调用doFilter方法来处理请求,并将ServletRequest接口、ServletResponse接口、FilterChain接口的实现类对象传入参数。
请求和响应对象真实类型是HttpServletRequest和HttpServletResponse

案例----统一设置编码格式

在Java Web项目中一定会使用到Servlet类,但Servlet类会需要我们对request和response中的字符集编码进行配置,这时如果Servlet类过多,字符集编码发生变化时修改起码会很麻烦。所以可以使用拦截,将字符集编码
配置等工作我们可以放到Filter类中来实现。

  1. 根据上面的步骤,我们创建了一个Filter类,这时候我们需要用到doFilter方法,在方法中编写字符集编码配置代码。
    代码如下:
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		//FilterChain是过滤器链
		//HttpServletRequest 是 ServletRequest接口的子接口,HttpServletResponse同理
		//如想使用子接口独有的方法,就要将ServletRequest强转为HttpServletRequest
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse resp = (HttpServletResponse) response;
		
		//因在web.xml修改过字符编码,所以只需修改POST的字符集
		req.setCharacterEncoding("utf-8");
		//放行   doFilter()方法,可以将请求和响应对象放行
		chain.doFilter(req, resp);
		
		/*
		 * 若未在web.xml修改过字符编码,可以使用以下方法
		 * 
		 * 获取到提交的方式
		 * String method = request.getMethod();
		 * 
		 * 修改POST的字符集
		 * req.setCharacterEncoding("utf-8");
		 * 
		 * 获取参数
		 * String uname = req.getParameter("uname");
		 * 
		 * 判断是否是GET方式提交
		 * if("GET".equals(method)) {
		 * 		修改该参数的字符编码
		 * 		uname = new String(uname.getBytes("ISO-8859-1"), "utf-8");
		 * }
		 * 
		 * 将修改过的参数存入域对象中
		 * req.setAttribute("uname", uname);
		 * 
		 * //放行   doFilter()方法,可以将请求和响应对象放行
		 * chain.doFilter(req, resp);
		 * 
		 * 后续如想显示、存入可以使用域对象中的get方法获取值
		 * 
		 * 但是这个方法并不好,如获取的参数很多,将非常麻烦
		 * 
		 */
		
	}
  1. 配置Filter,在web.xml
  <filter>
  	<filter-name>CharacterEncodedFilter</filter-name>
  	<filter-class>com.apps.web.filter.CharacterEncodedFilter</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>CharacterEncodedFilter</filter-name>
  	<url-pattern>/register</url-pattern>
  </filter-mapping>

常用配置项:
filter-class 指定的Filter类全限定类名

url-pattern 配置要拦截的资源
A. 以指定资源匹配。例如"/index.jsp"
B. 以目录匹配。例如"/servlet/"
C. 以后缀名匹配,例如"
.jsp"
D. 通配符,拦截所有web资源。"/*"

我这里的:

<url-pattern>/register</url-pattern>

指向的是Servlet映射名url-pattern,因为我们要拦截这个Servlet类,以目录匹配。可以看Servlet在web.xml中的代码

<servlet>
    <servlet-name>RegisterServlet</servlet-name>
    <servlet-class>com.apps.web.servlet.RegisterServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>RegisterServlet</servlet-name>
    <url-pattern>/register</url-pattern>
</servlet-mapping>
  1. 这时候,在我们访问/register时,便会被Filter类CharacterEncodedFilter拦截,修改过字符编码后,才会放行到Servlet类。
上一篇:JavaWeb知识小汇(9)——Filter


下一篇:Java Web:5.Filter