文档章节

javaweb开发之Filter

小米米儿小
 小米米儿小
发布于 2013/12/06 10:58
字数 1200
阅读 557
收藏 4

一、简介

在Servlet2.3规范中定义了过滤器,它对servlet容器调用servlet的过程进行拦截,从而在servlet进行响应处理的前后实现一些特殊的功能。

过滤器实现了一个责任链的模式。多个过滤器形成一个过滤器链,过滤器链中不同过滤器的先后顺序由部署文件web.xml中过滤器映射<filter-mapping>的顺序决定。

最先截获客户端请求的过滤器将最后截获Servlet/JSP的响应信息。

Servlet过滤器可以过滤的Web组件包括Servlet,JSP和HTML等文件。

Servlet过滤器可以应用在客户端和servlet之间、servlet和servlet或JSP页面之间,以及所包括的每个JSP页面之间。

二、原理

在Servlet中使用过滤器时,过滤器可以对客户端的请求进行处理。处理完成后,它会交给下一个过滤器处理,这样,客户的请求在过滤链里逐个处理,直到请求发送到目标为止。在目标处理结束后,会沿着最后一个过滤器反向一个个进行处理直至返回到客户端。

三、Filter相关接口

1. Filter接口

所有的Servlet过滤器都必须实现javax.servlet.Filter接口,并实现该接口中的三个方法:

init(FilterConfig filterConfig)

Servlet过滤器的初始化方法,Servlet容器创建Servlet过滤器实例后将调用该方法。该方法将读取web.xml文件中Servlet过滤器的初始化参数。

该方法在tomcat启动的时候执行。


doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

该方法完成实际的过滤操作,当客户端请求方法与过滤器设置匹配的URL时,Servlet容器将先调用过滤器的doFilter方法。FilterChain用户访问后续过滤器。

这里的ServletRequest和ServletResponse一般需要转换成具体的Servlet实现对于的对象,如:HttpServletRequest和HttpServletResponse。

有些过滤器比较消耗资源,所以需要防止重复过滤,可以在doFilter()方法中判断。



destroy()

Servlet容器在销毁过滤器实例前调用该方法,在该方法中释放Servlet过滤器占用的资源。

2. FilterConfig接口

Filter的init方法中提供了一个FilterConfig对象,提供相关的操作:

如获取Filter中配置的初始化参数:
<filter>
      <filter-name>LoginFilter</filter-name>
      <filter-class>cn.heimar.LoginFilter</filter-class>
      <init-param>
          <param-name>username</param-name>
          <param-value>admin</param-value>
      </init-param>
</filter>
在init方法中获取:
@Override
public void init(FilterConfig filterConfig) throws ServletException {
    //获取Filter初始化参数
    String username = filterConfig.getInitParameter("username");
}

3. 在Filter中访问application

ServletContext context = filterConfig.getServletContext();
或者在doFilter方法中根据转换好的request获取:
HttpServletRequest req = (HttpServletRequest)request;
ServletContext context = req.getSession().getServletContext();

四、定义过滤器

public class MyFilter implements Filter {

    public void init(FilterConfig fc) {
        //过滤器初始化代码
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain){
        //在这里可以对客户端请求进行检查
        //沿过滤器链将请求传递到下一个过滤器。
        chain.doFilter(request, response);
        //在这里可以对响应进行处理
    }

    public void destroy( ) {
        //过滤器被销毁时执行的代码
    }

}

五、过滤器映射

在web.xml文件中添加如下代码来声明Filter:
<filter>
    <filter-name>MyFilter</filter-name>
    <filter-class>
        cn.edu.uibe.webdev.MyFilter
    </filter-class>
    <init-param>
        <param-name>developer</param-name>
        <param-value>TongQiang</param-value>
    </init-param>
</filter>
<!--针对一个Servlet做过滤-->
<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <servlet-name>MyServlet</servlet-name>
</filter-mapping>
<!--针对URL Pattern做过滤-->
<filter-mapping>
    <filter-name>MyFilter</filter-name>
    <url-pattern>/book/*</url-pattern>
</filter-mapping>

/* 拦截所有资源及不存在的资源

*.jsp 拦截所有jsp文件

默认情况下forward方式不会被过滤。一般是需要过滤的,方式是在filter-mapping中添加<dispatcher>FORWARD</dispatcher>,该值默认是request,添加时为了防止覆盖request,需要把该值也添加。

六、常见应用

可以对客户提交的数据进行重新编码。
使浏览器不缓存页面。
过滤不和谐的文字。

可以验证用户是否登录。


对客户端提交的数据进行重新编码示例:

EncodingFilter.java

package cn.heimar.filter.encoding;

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;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class EncodingFilter implements Filter {
	/**
	 * 设置编码格式
	 */
	private String encoding;

	/**
	 * 是否需要强制转码
	 */
	private boolean forceEncoding = false;

	@Override
	public void init(FilterConfig config) throws ServletException {
		encoding = config.getInitParameter("ENCODING");
		String force = config.getInitParameter("FORCE_ENCODING");
		if (force != null)
			forceEncoding = Boolean.valueOf(force);
	}

	@Override
	public void doFilter(ServletRequest req, ServletResponse resp,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) resp;

		if ((request.getCharacterEncoding() == null || forceEncoding)
				&& encoding != null){
			request.setCharacterEncoding(encoding);
                }
		response.setCharacterEncoding(encoding);
		chain.doFilter(req, resp);
	}

	@Override
	public void destroy() {

	}

}
web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	id="WebApp_ID" version="2.5">

	<filter>
		<filter-name>EncodingFilter</filter-name>
		<filter-class>cn.heimar.filter.encoding.EncodingFilter</filter-class>
		<!-- 配置编码格式 -->
		<init-param>
			<param-name>ENCODING</param-name>
			<param-value>utf-8</param-value>
		</init-param>
		<!-- 配置是否强转 -->
		<init-param>
			<param-name>FORCE_ENCODING</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>
	
	<servlet>
		<servlet-name>LoginServlet</servlet-name>
		<servlet-class>cn.heimar.filter.encoding.LoginServlet</servlet-class>
	</servlet>
	
	<filter-mapping>
		<filter-name>EncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<servlet-mapping>
		<servlet-name>LoginServlet</servlet-name>
		<url-pattern>/login</url-pattern>
	</servlet-mapping>

</web-app>

© 著作权归作者所有

共有 人打赏支持
小米米儿小
粉丝 39
博文 114
码字总数 83921
作品 0
成都
程序员
私信 提问
Druid使用起步—在javaWeb项目中配置监控

当我们在javaWEB项目中使用到druid来作为我们的连接池的时候,一定不会忘了添加监控功能。下面我们就来看一下,在一个简单的web项目中(尚未使用任何框架)我们是如果来配置我们的web.xml来完成...

明月照大江
2013/08/15
0
4
Javaweb组件--Filter

今天讲的是Javaweb的三大组件之:Filter Filter ,过滤器,主要是对web服务器管理的所有web资源,比如Jsp,Servlet,静态图片等进行拦截,从而实现一些特殊的功能。比如权限控制,请求拦截,...

a1ie2
2017/11/16
0
0
Druid使用配置初步理解

Druid是什么? Druid首先是一个数据库连接池。Druid是目前最好的数据库连接池,在功能、性能、扩展性方面,都超过其他数据库连接池,包括DBCP、C3P0、BoneCP、Proxool、JBoss DataSource。 ...

chenhuaming
2016/10/08
157
0
javaweb学习总结——Filter(过滤器)学习

一、Filter简介   Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文...

LittlerBeans
2015/10/13
83
1
Struts2知识点小结(一)

一、struts2简介   1、Struts2是一个基于MVC设计模式的Web应用框架 只要是web层框架 一般就会遵守MVC设计模式 2、struts2与struts1的关系? 没关系 WebWork基于xwork 3、struts2是一个可插拔...

it~沃克尔
08/08
0
0

没有更多内容

加载失败,请刷新页面

加载更多

通过Docker容器连接代理Wormhole

Wormhole 是一个能识别命名空间的由 Socket 激活的隧道代理。可以让你安全的连接在不同物理机器上的 Docker 容器。可以用来完成一些有趣的功能,例如连接运行在容器本机的服务或者在连接后创...

Linux就该这么学
18分钟前
1
0
从架构到平台, POWER 9处理器最全解读

本文根据IBM中国芯片设计部门高级经理尹文,在「智东西公开课」的超级公开课IBM专场《POWER 9-认知时代的驱动力》 上的系统讲解整理而来。 本次讲解中,尹文老师从内核微架构、总线互连、异构...

Mr_zebra
21分钟前
1
0
openjdk和oraclejdk有什么区别吗?

1.授权协议的不同:OpenJDK采用GPL V2协议放出,而SUN JDK则采用JRL放出。两者协议虽然都是开放源代码的,但是在使用上的不同在于GPL V2允许在商业上使用,而JRL只允许个人研究使用。 2.Open...

吴伟祥
22分钟前
2
0
c++基类析构函数要声明为virtual的原因

更深层的原因不知道,不过标准规定,如果不声明为virtual,那么将会导致未定义行为。个人测试结果表明,如果不声明为virtual,那么派生类的析构函数将不会得到调用

安非他命
28分钟前
1
0
CentOS 7下protobuf的源码编译安装

protobuf的github地址:https://github.com/google/protobuf支持多种语言,有多个语言的版本,本文采用的是在CentOS 7下编译源码进行安装。 github上有详细的安装说明:https://github.com/...

xtof
35分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部