1、定义
过滤器是Web程序中的可重用组件,是一个程序。它先于与之相关的Servlet或JSP页面运行在服务器上。过滤器可以附加到一个或多个Servlet或JSP页面上,并且可以检查进入这些资源的请求信息。Filter接口是过滤器API的核心,所有的过滤器都必须直接或间接地实现该接口。可以在客户和资源之间建立多个过滤器,从而形成过滤器链(Filter Chain)。
2、处理方式
过滤器是客户端与目标资源间的中间层组件,属于Web容器的一部分,用于拦截客户端的请求与响应信息。
处理步骤如下:
①当Web容器接收一个客户端请求时,Web容器判断此请求是否与过滤器对象相关联,如果相关联,容器将这一请求交给过滤器进行处理。
②在处理过程中,过滤器可以对请求进行操作,如更改请求中的信息数据,在过滤器处理完成之后,再将这一请求交给其他业务进行处理。
③当所有业务处理完成,需要对客户端进行响应时,容器又将响应交给过滤器处理,过滤器处理响应完成后将响应发送到客户端。
注意:在Web程序的应用过程中可以放置多个过滤器,Web容器对多个过滤器的处理方式为链式处理,即容器首先将客户端请求交给第一个过滤器处理,处理完成之后交给下一个过滤器处理,以此类推,直到最后一个过滤器对象。
3、生命周期
过滤器类实现的Filter接口声明了三个方法,分别是init()、doFilter()、destory()方法,它们是过滤器的生命周期方法。
4、应用
①当身份不同的用户访问同一个页面时进行过滤,例如:管理员页面只能管理员账户才能进入
1)Web应用程序目录
2)登录页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<%-- 这里的action使用的是相对路径,代表进入该路径--%>
<form action="Login" method="post">
用户:<input type="text" name="username">
密码:<input type="password" name="userpwd">
<input type="submit" value="登录">
</form>
</body>
</html>
3)处理登录请求的Servlet类
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
HttpSession session = request.getSession();
session.setAttribute("username",username);
// 对不同的用户执行不同的重定向操作
if (username.equals("admin")) {
// 这里使用的是相对路径,代表进入该路径
response.sendRedirect("admin/admin_page.jsp");
}
else if(username.equals("user")) {
// 这里使用的是相对路径,代表进入该路径
response.sendRedirect("user/user_page.jsp");
}
}
}
4)在Web.xml中对该Servlet进行配置
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>cn.qi.servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/Login</url-pattern>
</servlet-mapping>
5)用户页面和管理员页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>用户页面</title>
</head>
<body>
你好:<%=(String)(session.getAttribute("username"))%><br />
<%-- 超链接要使用绝对路径(包含项目路径)--%>
<a href="/Filter_test_war_exploded/admin/admin_page.jsp">查看管理员界面</a>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>管理员页面</title>
</head>
<body>
你好:<%=(String)(session.getAttribute("username"))%><br />
<%-- 超链接要使用绝对路径--%>
<a href="/Filter_test_war_exploded/user/user_page.jsp">查看用户页面</a>
</body>
</html>
6)过滤器(实现Filter接口即可)
public class LoginFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
// 处理HTTP请求和响应时需要将ServletRequest强制类型转换为HttpServletRequest
String username = (String) ((HttpServletRequest)req).getSession().getAttribute("username");
String requestURI = ((HttpServletRequest)req).getRequestURI();
HttpServletResponse res = (HttpServletResponse)resp;
if (username != null && username.equals("user") && requestURI.startsWith("/Filter_test_war_exploded/admin")) {
// 页面重定向时使用相对路径
res.sendRedirect("../access_denied.jsp");
}
else if (username != null && username.equals("admin") && requestURI.startsWith("/Filter_test_war_exploded/user")) {
res.sendRedirect("../access_denied.jsp");
}
// 请求转到下一资源或下一过滤器
chain.doFilter(req, resp);
}
public void init(FilterConfig config) throws ServletException {
}
}
7)在Web.xml对该过滤器进行配置
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>cn.qi.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<!-- 这里使用的是相对路径-->
<url-pattern>/admin/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<!-- 这里使用的是相对路径-->
<url-pattern>/user/*</url-pattern>
</filter-mapping>