filter的意思简单的说就是过滤器,它的作用就是当用户请求一个url之前,可以预先做一些处理,当请求完url返回给用户之前还可以做一些处理(所以filter的功能十分的强大,如果想做的话可以强大到让用户,不能访问请求的url的程度。。。)
接口javax.servlet.Filter
void init(FilterConfig filterConfig)
可以在此方法中完成Filter需要初始化的内容,在一个filter提供服务之前肯定会先调用此方法
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
当用户访问的url或者servlet被配置了使用此filter时,servlet/jsp容器会调用此方法,每次访问调用一次。chain参数为一个FilterChain接口的对象,可以简单的理解成chain包含了访问一个url上所有的需要调用的方法。
void destroy()
当不需要一个filter再提供服务时调用,容器会调用此方法
filter的工作模式如附件图片:
假如用户访问的一个url有两个filter的时候。
servlet容器会先调用最外层的filter(Filter1)的doFilter()方法,然后在由Filter1中调用的chain.doFilter方法将控制权返回给容器,接着容器调用第二层filter(Filter2)的doFilter方法,然后在由Filter2中调用的chain.doFilter方法将控制权返回给容器,这个时候容器才能去访问真正的需要请求的servlet和jsp,但servlet和jsp执行完毕以后,会运行Filter2中doFilter方法调用的chain.doFilter方法后剩余的代码片断,之后再运行Filter1中doFilter方法调用的chain.doFilter方法后剩余的代码片断。
Filter对应的请求方式有4种:request、forward、include、error
request:当用户直接请求一个网页时才会通过此filter,当用户通过RequestDispatcher(会再后面详细介绍该类的方法)的forward不会通过该filter
forward: 当用户通过RequestDispatcher的forward方法访问对应的url时才会通过该filter
include:当用户通过RequestDispatcher的include方法访问对应的url时才会通过该filter
error:当用户的请求通过错误处理机制的时候才会通过该filter(目前不准备详细论述)。
一个filter可以对应几种请求方式,但是如果配置时不写请求方式的话,默认方式为request。
下面先举一个例子看下filter工作的过程:
FilterFirst:
package squall.servlet.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 FilterFirst implements Filter
{
public void destroy()
{
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException
{
System.out.println("Begin First Filter!");
chain.doFilter(request, response);
System.out.println("After First Filter!");
}
public void init(FilterConfig config) throws ServletException
{
}
}
FilterSecond:
package squall.servlet.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 FilterSecond implements Filter
{
public void destroy()
{
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException
{
System.out.println("Begin Second Filter!");
chain.doFilter(request, response);
System.out.println("After Second Filter!");
}
public void init(FilterConfig config) throws ServletException
{
}
}
部署时修改web.xml如下:
在第一个<servlet>标签前添加:
<filter>
<filter-name>FilterFirst</filter-name>
<filter-class>squall.servlet.filter.FilterFirst</filter-class>
</filter>
<filter>
<filter-name>FilterSecond</filter-name>
<filter-class>squall.servlet.filter.FilterSecond</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterFirst</filter-name>
<url-pattern>/HelloServlet</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>FilterSecond</filter-name>
<url-pattern>/HelloServlet</url-pattern>
</filter-mapping>
将filter标签放置在一起,将filter-mapping标签放在再一起,顺序根据filter-name一致。这里的filter-mapping的顺序即为:假如我们访问的一个url有两个filter时,filter的先后顺序,web.xml中filter-mapping在前面的filter先被执行。
部署完毕之后我们访问:http://127.0.0.1:8080/train/HelloServlet
可以看到tomcat管理控制台输出如下:
Begin First Filter!
Begin Second Filter!
After Second Filter!
After First Filter!
上面的例子可以看出filter工作的过程和我们上面的图片一致。
下面我们来举一个比较贴近实际的例子看一下filter的方便之处。
下面的例子用于常见的解决中文乱码的问题,我们为了防止中文乱码经常需要调用
HttpServletRequest和HttpServletResponse的setCharacterEncoding方法,底下的这个filter的例子实现了,采用filter来解决这个问题。
Filterparam.html:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<META http-equiv="Content-Type" content="text/html; charset=GBK" />
<script type="text/javascript">...
function changeaction()
{
var a = document.getElementsByName("filter");
for(i = 0; i < a.length; i++)
{
if(a[i].checked==true)
{
fm.action=a[i].value;
break;
}
}
}
</script>
<title>filterparameter.html</title>
</head>
<body bgcolor="#FDF5E6">
<h2>Filter中文乱码示范</h2>
<form name ="fm" method="post" action="FilterShowParameter/No">
<p>姓名:<input type="text" name="username" size="15" /> </p>
<p>使用filter:
<input name="filter" value="FilterShowParameter/No" type="radio" onclick="changeaction()" checked />
不使用
<input name="filter" value="FilterShowParameter/Yes" type="radio" onclick="changeaction()" />
使用
</p>
<p>
<input value="确认" type="submit" />
<input value="清除" type="reset" />
</p>
</form>
</body>
</html>
直接放在train目录下
FilterShow:
package squall.servlet.basic;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class FilterShow extends HttpServlet
{
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
showParam( req, resp);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
showParam( req, resp);
}
private void showParam(HttpServletRequest req, HttpServletResponse resp) throws IOException
{
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
String docType = "<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> ";
String name = req.getParameter("username");
out.println(docType + "<HTML> " + "<HEAD><TITLE> showparam"
+ "</TITLE></HEAD> " + "<BODY BGCOLOR="#FDF5E6"> "
+" 姓名:" + name + " </br>"
);
out.println("</body></html>");
}
}
部署时将FilterShow mapping至/FilterShowParameter/*
EncodingFilter:
package squall.servlet.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 EncodingFilter implements Filter
{
public void init(FilterConfig config) throws ServletException
{
String str = config.getInitParameter("encoding");
if (str != null && !"".equals(str))
encoding = str;
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException
{
System.out.println("encoding is " + encoding);
if(encoding != null)
{
request.setCharacterEncoding(encoding);
response.setCharacterEncoding(encoding);
}
chain.doFilter(request, response);
}
public void destroy()
{
}
private String encoding = null;
}
EncodingFilter的功能就是将request和response setCharacterEncoding为预先定义好的encoding。getInitParameter 将在以后介绍。
EncodingFilter部署方式:
在web.xml最后一个</filter>下添加
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>squall.servlet.filter.EncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>GBK</param-value>
</init-param>
</filter>
然后在最后一个</filter-mapping>下添加:
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/FilterShowParameter/Yes</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
部署完毕后访问http://127.0.0.1:8080/train/filterparam.html
输入姓名为中文以后,如果使用filter 选择为 不使用 则会看到乱码
选择使用filter后 则会看到正确的中文。
上面的例子是对REQUEST和FORWARD使用filter。
关于filter-mapping的include方式做一个简单的说明,如下:
<filter-mapping>
<filter-name>FilterName</filter-name>
<servlet-name>HelloServlet</servlet-name>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
include方式时必须将<url-pattern>修改为<servlet-name>
上面的filter-mapping的含义为:
当HelloServlet这个servlet里调用RequestDispatcher的include时,才会通过此filter。
filter的功能远远不只上面举的例子,filter还可以对servlet和jsp输出至客户端的内容进行修改,还可以用来判断是否满足一些条件,假如不满足条件就不让访问者访问相应的条件,这里就不做一一的介绍了。
- 大小: 11.2 KB
分享到:
相关推荐
Servlet API的核心概念包括Servlet、Filter和Listener。Servlet是一种Java类,用于扩展Web服务器的功能,处理来自客户端(如浏览器)的HTTP请求,并向客户端发送响应。例如,一个Servlet可能接收表单数据,处理业务...
通过配置`<filter>`和`<filter-mapping>`元素在web.xml中指定Filter的使用。 综上所述,`javax.servlet` jar包和`javax.servlet.jsp` jar包是Java Web开发不可或缺的部分,它们提供了处理HTTP请求的核心接口和类,...
4. **动态注册**:除了使用注解外,Servlet 3.0还允许在应用程序初始化时动态地注册Servlet、Filter和Listener。这使得开发者可以在运行时根据需要调整应用程序的配置。 5. **更强大的过滤器**:Filter接口进行了...
它包含了一些基本的Servlet和Filter接口,如`Servlet`, `GenericServlet`, `HttpServlet`, `Filter`, `ServletConfig`等。虽然3.1版本提供了更多高级功能,但2.5版本仍被许多老项目和不支持新规范的服务器使用。 3....
4. `javax.servlet.http.HttpServletRequest`和`javax.servlet.http.HttpServletResponse`:这两个类分别代表了HTTP请求和响应对象,它们封装了HTTP协议的细节,使得开发者可以方便地获取请求参数、设置响应头和状态...
本篇文章将围绕jakarta-servletapi-4-src.zip这个源码包,深入剖析Servlet API 4.0的关键特性与实现原理。 一、Servlet接口与生命周期 Servlet接口是所有Servlet的基础,它定义了Servlet的主要方法,如`init()`, `...
这个包包含了Servlet API中的所有类和接口,如`ServletRequest`、`ServletResponse`、`Filter`等。通过查看这些源代码,我们可以了解这些核心类和接口的实现细节,从而提高我们的编程技能和解决问题的能力。 总的来...
javax.servlet.Filter javax.servlet.Servlet javax.servlet.FilterChain javax.servlet.http.Cookie javax.servlet.FilterConfig javax.servlet.ServletConfig javax.servlet.GenericServlet javax.servlet....
"Servlet-1-filter-3.rar"文件很可能包含了实现这一功能的示例代码或教程,供开发者参考学习。使用Filter进行防乱码控制是一种高效且灵活的方法,它可以应用于各种Web应用中,确保用户数据的正确性和一致性。
1. **注解支持**:Servlet 2.5开始支持注解(Annotation),开发者可以使用`@WebServlet`、`@WebFilter`和`@WebListener`等注解来声明Servlet、Filter和Listener,减少了web.xml配置文件的依赖。 2. **过滤器链的...
Servlet-API 2.5是Java Servlet规范的第3版,它提供了对Servlet、Filter和Listener的定义,这些是构建Web应用程序的基本组件。这个版本引入了一些新特性,如: 1. **WebSocket前驱**:虽然Servlet 2.5本身不直接...
- **注解驱动的配置**:Servlet 3.0引入了注解来替代传统的web.xml部署描述符,使得开发者可以直接在类或方法上使用注解进行配置,如`@WebServlet`,`@WebFilter`,`@WebListener`等。 - **异步处理**:Servlet ...
Servlet 3.0允许开发者使用注解(@WebServlet, @WebFilter, @WebListener)来声明Servlet、过滤器和监听器,而不是传统的web.xml配置文件。这种方式更简洁,减少了配置错误的可能性,同时使得代码更加模块化。 4. **...
1. **Filter Chain**:Servlet API 2.4引入了过滤器(Filter)的概念,这是一种预处理或后处理请求和响应的方法。过滤器可以在请求到达目标Servlet之前进行拦截,进行诸如身份验证、内容编码转换等操作,也可以在...
- 注解支持:引入了注解来简化Servlet和过滤器的配置,如`@WebServlet`、`@WebFilter`和`@WebListener`,减少了web.xml文件的依赖。 - 异步处理:Servlet 2.5引入了异步处理能力,允许Servlet在接收到请求后将控制权...
4. **ServletConfig接口**:Servlet的配置信息由Servlet容器在Servlet初始化时提供,包含在ServletContext中的Servlet特定信息,如初始化参数。 5. **ServletContext接口**:代表一个Web应用的上下文,提供了全局...
4. **异步处理**:Servlet 3.0引入了异步处理能力,允许Servlet在处理请求时释放线程,提高服务器性能。通过调用`HttpServletRequest.startAsync()`方法,开发者可以启动一个异步上下文,然后在后台执行长时间运行的...
Filter接口允许在请求到达Servlet之前对其进行拦截和修改,例如实现权限检查、数据转换等。Filter可以组成FilterChain,按照定义的顺序依次执行。 9. **Session管理** Servlet API提供了`HttpSession`接口,用于...
虽然Servlet仍然是构建Web应用的基础,但随着Java EE(现在称为Jakarta EE)的发展,出现了更高级的组件模型,如Filter和Servlet 3.0引入的Asynchronous Servlet。Spring MVC和JSF等框架也提供了更抽象的编程模型,...