JAVAWEB学习文章索引点这里
1.Filter介绍
Filter被称作过滤器或拦截器,其基本功能就是对Servlet容器调用Servlet的过程进行拦截,从而在Servlet进行响应处理前后实现一些特殊功能。
Filter接口中的方法
| init(FilterConfig filterConfig) | 用于初始化过滤器,由服务器开启时自动调用一次。如果要使用filterConfig对象就该在本方法中使用。 |
| doFilter(ServletRequest request, ServletResponse response, FilterChain chain) | request和response是web服务器或上一个filter传过来的请求和响应对象。chain代表当前filter链的对象,它可以调用doFilter(),把请求交给下一个filter或目标程序 |
| destoro() | 该方法在web服务器卸载filter对象之前被调用,该方法用于释放被filter对象打开的资源,如关闭数据库或者io流 |
下面演示一下filter
servlet:
package com.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/MyServlet")
public class MyServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("正在访问servlet");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
filter:
package com.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;
import javax.servlet.annotation.WebFilter;
@WebFilter("/MyServlet")
public class MyFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("正在访问filter");
//chain.doFilter(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
然后打开浏览器,输入servlet的访问路径,控制台的内容为”正在访问filter”,因为使用注解配置的filter和servlet的虚拟路径是相同的,所以在访问后被过滤器拦截住了。如果要放行就使用chain.doFilter(request, response)方法就会继续执行,访问到servlet。
使用配置文件配置filter
在可以使用注解之前,一般在要使用filter的时候都需要在web.xml中进行配置。
<filter>
<filter-name>myfilter</filter-name>
<filter-class>com.filter.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myfilter</filter-name>
<url-pattern>/MyServlet</url-pattern>
</filter-mapping>
配置方式和道理和servlet相似,不同的地方在于,这里的url地方填的是需要被过滤的servlet的虚拟路径,而不是访问filter的路径。当我们直接访问servlet的时候,就会被拦截住。
映射路径的模糊配置
上面我们使用的配置方式是一种准确的配置方式,直接指定了需要过滤的路径。
不过可以过滤的也不只是servlet,也可是是html文件。
如果要配置很多路径的话就可以使用模糊配置:
<url-pattern>/*</url-pattern>:拦截所有的内容
<url-pattern>/test/*</url-pattern>:拦截test路径下的所有内容
<url-pattern>*.do</url-pattern>:拦截所有的以.do结尾的路径
特别注意!!!用.do,.action的时候前面别加/,匹配不会成功,并且高版本tomcat还会启动报错!
拦截不同访问方式的访问访问请求
有四种方式,默认为REQUEST
REQUEST:直接访问页面的时候,会被过滤。如果是通过RequestDispatcher的include()或forward()方法访问的时,过滤器不会被调用。
INCLUDE:通过RequestDispatcher的include()时,可以过滤。其他方式不会
FORWARD:通过RequestDispatcher的forward()访问时,可以过滤,其他方式不会。
ERROR:如果目标资源是通过声明式异常处理机制调用的时候,过滤器会被调用,其他的方式不会。
下面,以REQUEST和FORWARD举例,编写以下页面
1,test.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
test1.jsp
</body>
</html>
2,它的过滤器
package com.filter;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
@WebFilter(urlPatterns="/test1.jsp")
public class TestFilter1 implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.print("被拦截了");
//chain.doFilter(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
3,一个进行转发的servelt
package com.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/TestServlet1")
public class TestServlet1 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//转发到test1.jsp
request.getRequestDispatcher("/test1.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
然后我们直接访问servlet,其将转发到test1.jsp。显示结果为”test1.jsp”,也就是说拦截器没有被调用。
然后我们修改过滤器的注解如下(将访问方式改为FORWARD)
@WebFilter(urlPatterns="/test1.jsp",dispatcherTypes= {DispatcherType.FORWARD})
然后在访问servlet,最后页面结果是“被拦截了”。
filter链
不同的过滤器可以作用于同一个servlet。它们的作用顺序按照它们在servlet中的配置顺序,先配置的优先进行过滤。
这里我们采用注解的方式访问:
filter
package com.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;
import javax.servlet.annotation.WebFilter;
@WebFilter(filterName="b",urlPatterns="/MyServlet")
public class MyFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("正在访问filter:before");
chain.doFilter(request, response);
System.out.println("正在访问filter:after");
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
filter2
package com.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;
import javax.servlet.annotation.WebFilter;
@WebFilter(filterName="a",urlPatterns="/MyServlet")
public class MyFilter2 implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("正在访问filter2:before");
chain.doFilter(request, response);
System.out.println("正在访问filter2:after");
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
filter3
package com.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;
import javax.servlet.annotation.WebFilter;
@WebFilter(filterName="c",urlPatterns="/MyServlet")
public class AMyFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("正在访问filter3:before");
chain.doFilter(request, response);
System.out.println("正在访问filter3:after");
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
然后打开浏览器,访问前面介绍到的MyServlet这个Servlet。结果如下
正在访问filter3:before
正在访问filter:before
正在访问filter2:before
正在访问servlet
正在访问filter2:after
正在访问filter:after
正在访问filter3:after
在注解中,我分别将filter的名字设置为a、b、c可以看到名字并没有影响到filter的访问顺序,影响到访问顺序的是它们类名(AMyFilter、MyFilter、MyFilter2)
并且,请求和响应都以chain.doFilter(request, response)来进行分隔,该方法以前的内容在请求的时候执行,该方法以后的内容在响应的时候执行。
FilterConfig
FilterConfig主要用于获取配置信息,示例如下。这里使用注解进行配置。
package com.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;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
@WebFilter(filterName="FilterConfigTest", urlPatterns="/test2.jsp",
initParams={@WebInitParam(name="a",value="1"),
@WebInitParam(name="b",value="2")
})
public class FilterConfigTest implements Filter {
FilterConfig fc = null;
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//输出过滤器名称
System.out.println(fc.getFilterName());
//输出上下文路径
System.out.println(fc.getServletContext().getContextPath());
//获取初始化参数a的值
System.out.println(fc.getInitParameter("a"));
chain.doFilter(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {
fc = fConfig;
}
}
本文深入讲解Java Web中的Filter机制,包括Filter的基本概念、工作原理、配置方法及多种应用场景。介绍了如何通过Filter实现请求预处理与后处理,以及如何配置Filter链来对多个Filter进行有序调用。
1090

被折叠的 条评论
为什么被折叠?



