目录
一、简介:
- 过滤器用于实现对Web资源的拦截,完成特殊操作,尤其是对请求的预处理。
- 过滤器的应用场景:Web资源权限的访问限制,请求字符集编码处理,内容敏感字符词汇过滤,响应信息压缩等。
- 过滤器的工作流程:
- 过滤器的生命周期:
① Web 应用启动时,Web服务器创建 Filter 的实例对象、进行对象初始化。②当请求访问与过滤器关联的Web资源时,过滤器拦截请求,完成指定功能。③Filter对象创建后会驻留内存,当Web应用移除或服务器停止时才销毁。 - 过滤器的实现步骤:①编写Java类的 Filter接口 并实现其 doFilter() 方法。②在 web.xml 中对 filter类进行注册,并设置所拦截的资源。
- 过滤器链:在一个 web应用中,多个过滤器组合起来称之为一个过滤器链。过滤器的调用顺序取决于在web.xml文件中的注册顺序。
- 注意过滤器类实现的是 javax.servlet.Filter 接口。
二、过滤器的配置参数:
- 使用好处:修改不用动类,只需修改web.xml。
- 用法:
①先在web.xml中设置: 写在<filter>对里
<!-- 配置初始化参数(此处配置了2个) -->
<init-param>
<param-name>systemName</param-name> <!-- 初始化参数名称 -->
<param-value>filter Encoding</param-value> <!-- 初始化参数的值 -->
</init-param>
<init-param>
<param-name>version</param-name>
<param-value>1.0</param-value>
</init-param>
②在过滤器类:
private FilterConfig config; //创建一个过滤器的配置参数对象
在init()方法中添加:
@Override
public void init(FilterConfig config) throws ServletException {
this.config=config; //传入配置参数对象
}
在doFilter()方法里添加:
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("do filter!");
String systemName=config.getInitParameter("systemName");
String version=config.getInitParameter("version");
System.out.println("systemName:"+systemName);
System.out.println("version:"+version);
chain.doFilter(request, response); //通知服务器请求的拦截处理已完成
}
重启服务器,访问页面后控制台输出:
例:
login.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String username = request.getParameter("username");
String password = request.getParameter("password");
session.setAttribute("loginUser", username);
response.sendRedirect(request.getContextPath() + "/message.jsp"); //request.getContextPath()获取当前的系统路径
%>
index.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String flag=request.getParameter("flag");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录</title>
<link href="form.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
var flag='<%=flag%>';
if(flag=='1'){
alert("其先登录哈!");
}
</script>
</head>
<body>
<form action="login.jsp" method="post" class="smart-green">
<h1>登录</h1>
<label> <span>用户名:</span> <input id="username" type="text"
name="username">
</label> <label> <span>密码:</span> <input id="password" type="password"
name="password">
</label>
<label>
<input type="submit" class="button" value="登录"/>
</label>
</form>
</body>
</html>
message.jsp:
<%@page import="com.message.Message"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String user = (String) session.getAttribute("loginUser");
String subFlag = request.getParameter("subFlag");
List<Message> list = (List<Message>)session.getAttribute("list");
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>留言板</title>
<link href="form.css" rel="stylesheet" type="text/css" />
<link href="table.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
var subFlag='<%=subFlag%>';
if (subFlag == '1') {
alert("留言成功!");
}
</script>
</head>
<body>
<form action="messageSub.jsp" method="post" class="smart-green">
<h1>留言板</h1>
<label> <span>留言人:</span> <input id="user" type="text"
name="user" value="<%=user%>" readonly> <!-- readonly表示只读 -->
</label>
<label> <span>标题:</span> <input id="title" type="text"
name="title" value="">
</label>
<label> <span>内容:</span> <textarea id="content" type="text"
name="content" value=""></textarea>
</label> <span> </span>
<label>
<input type="submit" class="button" value="提交"/>
</label>
</form>
<br />
<table id="table-3" width="85%" align="center">
<tr>
<th width="15%">留言人</th>
<th width="15%">标题</th>
<th width="70%">内容</th>
</tr>
<%
if (list != null) {
for (Message message : list) {
%>
<tr>
<td><%=user%></td>
<td><%=message.getTitle()%></td>
<td><%=message.getContent()%></td>
</tr>
<%
}
}
%>
</table>
</body>
</html>
messageSub.jsp:
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@page import="com.message.Message"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String title = request.getParameter("title");
String content = request.getParameter("content");
Message message = new Message();
message.setContent(content);
message.setTitle(title);
List<Message> list = (List<Message>) session.getAttribute("list");
if (list == null) {
list = new ArrayList<Message>();
session.setAttribute("list", list);
}
list.add(message);
response.sendRedirect(request.getContextPath() + "/message.jsp?subFlag=1");
%>
CharacterEncodingFilter.java:解决中文乱码
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.jsp.jstl.core.Config;
public class CharacterEncodingFilter implements Filter {
private FilterConfig config; //创建一个过滤器的配置参数对象
//getter和setter方法不用写也行,只是习惯
public FilterConfig getConfig() {
return config;
}
public void setConfig(FilterConfig config) {
this.config = config;
}
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
request.setCharacterEncoding(config.getInitParameter("charset")); //解决中文乱码
chain.doFilter(request, response); // 通知服务器请求的拦截处理已完成
}
@Override
public void init(FilterConfig config) throws ServletException {
this.config=config; //传入配置参数对象
}
}
SessionFilter.java:对登录安全处理
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.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SessionFilter implements Filter {
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 转换:request和response转成Http对象,因为过滤器总对Http请求进行处理
HttpServletRequest request1 = (HttpServletRequest) request;
HttpServletResponse response1 = (HttpServletResponse) response;
String loginUser = (String) request1.getSession().getAttribute("loginUser");
if (loginUser == null) {
response1.sendRedirect(request1.getContextPath() + "/index.jsp?flag=1");
return;
} else {
chain.doFilter(request, response); // 通知服务器请求的拦截处理已完成
}
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>Filter</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 1.注册过滤器 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.filter.CharacterEncodingFilter</filter-class> <!-- 包名.类名 -->
<!-- 配置初始化参数(此处配置了2个) -->
<init-param>
<param-name>charset</param-name> <!-- 初始化参数名称 -->
<param-value>UTF-8</param-value> <!-- 初始化参数的值 -->
</init-param>
</filter>
<!-- 2.配置拦截请求映射 -->
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 注意多个过滤器的配置顺序 -->
<filter>
<filter-name>sessionFilter</filter-name>
<filter-class>com.filter.SessionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>sessionFilter</filter-name>
<url-pattern>/message.jsp</url-pattern>
</filter-mapping>
</web-app>
三、Java过滤器配置:
filter-mapping的子元素dispatcher(针对的是<url-pattern>对的映射)的取值可为:
- REQUEST(默认):当我们直接访问页面时,web服务器认为资源调用方式是request方式,执行调用过滤器。
如:
<!--当直接访问test2.jsp这个资源时,过滤器会被调用和执行-->
<filter-mapping>
<filter-name>t过滤器名字</filter-name>
<url-pattern>/test2.jsp</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
- INCLUDE:
如
<!--当访问test2.jsp这个资源,且访问方式是include时,过滤器会被调用和执行-->
<filter-mapping>
<filter-name>t过滤器名字</filter-name>
<url-pattern>/test2.jsp</url-pattern>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
- FORWORD:
如:
<!--当访问test2.jsp这个资源,且访问方式是FORWARD时,过滤器会被调用和执行-->
<filter-mapping>
<filter-name>t过滤器名字</filter-name>
<url-pattern>/test2.jsp</url-pattern>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
- ERROR
如:
<!--当发生404错误时会返回test2.jsp页面-->
<filter-mapping>
<filter-name>t过滤器名字</filter-name>
<url-pattern>/test2.jsp</url-pattern>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
<error-page>
<error-code>404</error-code>
<location>/test2.jsp</location>
</error-page>
可以配置多个dispatcher元素。