过滤器的作用:实现对web资源请求的拦截,完成特殊的操作,尤其是对请求的预处理。
过滤器的使用场景
- Web资源权限访问控制
- 请求字符集编码处理
- 内容敏感字符词汇过滤
- 响应信息压缩
过滤器的工作流程
过滤器的生命周期
- web 应用程序启动时,web 服务器创建Filter 的实例对象,以及对象的初始化。
- 当请求访问与过滤器关联的Web资源时,过滤器拦截请求,完成指定功能。
- Filter对象创建后会驻留在内存,在web应用移除或服务器停止时才销毁。
- 过滤器的创建和销毁由WEB服务器负责。
过滤器的实现步骤
1.编写java类实现Filter接口,并实现其doFilter方法。
2.在web.xml文件中对filter类进行注册,并设置所拦截的资源。
过滤器链
- 在一个web应用中,多个过滤器组合起来称之为一个过滤器链。
- 过滤器的调用顺序取决于过滤器在web.xml文件中的注册顺序
案例介绍
1.项目案例为Java Web应用程序,完成一个简单的数据提交功能。
2.增加中文编码字符集预处理过滤器,解决中文乱码问题。
3.增加系统用户登录安全控制过滤器,解决web资源访问控制问题
中文编码过滤器的实现
public class CharacterEncodingFilter implements Filter {
private FilterConfig config;
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
request.setCharacterEncoding(config.getInitParameter("charset"));// 根据过滤器配置字符集,设置请求字符集编码
// System.out.println("characterEncodingFilter 请求预处理");//测试过滤器(链)工作流程使用
chain.doFilter(request, response);
// System.out.println("characterEncodingFilter 响应后处理");//测试过滤器(链)工作流程使用
}
@Override
public void init(FilterConfig config) throws ServletException {
this.config = config;
}
public FilterConfig getConfig() {
return config;
}
public void setConfig(FilterConfig config) {
this.config = config;
}
}
用户登录安全控制过滤器实现
public class SessionFilter implements Filter {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest hrequest = (HttpServletRequest) request;// 涉及到HTTP请求处理,转型处理
HttpServletResponse hresponse = (HttpServletResponse) response;// 涉及到HTTP请求处理,转型处理
String loginUser = (String) hrequest.getSession().getAttribute("loginUser");// 判断用户是否完成了登录操作,session中是否存储用户名
if (loginUser == null) {
hresponse.sendRedirect(hrequest.getContextPath() + "/index.jsp?flag=1");// 未登录,系统强制重定向至登录页面
return;
} else {
chain.doFilter(hrequest, hresponse);
return;
}
}
@Override
public void init(FilterConfig config) throws ServletException {
}
}
在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>FilterDemo</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 字符集编码过滤器配置 -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>charset</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 用户登录安全控制过滤器配置 -->
<filter>
<filter-name>sessionFilter</filter-name>
<filter-class>filter.SessionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>sessionFilter</filter-name>
<url-pattern>/message.jsp</url-pattern>
</filter-mapping>
</web-app>
Message.java
public class Message {
private String title;
private String content;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String flag = request.getParameter("flag");
%>
<!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>用户登录</title>
<link href="form.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
var flag = '<%=flag %>';
if("1"==flag){
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>
<span> </span>
<label>
<input type="submit" class="button" value="登录"/>
</label>
</form>
</body>
</html>
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); //模拟登录操作,在session中存入登录用户的用户名
response.sendRedirect(request.getContextPath()+"/message.jsp");//重定向至留言板页面
%>
message.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.util.*,model.*" %>
<%
String user = (String)session.getAttribute("loginUser");
String subFlag = request.getParameter("subFlag");
List<Message> messages = (List<Message>)session.getAttribute("messages");
%>
<!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>留言板</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('1'==subFlag){
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/>
</label>
<label>
<span>标题 :</span>
<input id="title" type="text" name="title" value=""/>
</label>
<label>
<span>内容 :</span>
<textarea id="content" name="content"></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(messages!=null){
for(Message message : messages){
%>
<tr>
<td><%=user %></td>
<td><%=message.getTitle() %></td>
<td><%=message.getContent() %></td>
</tr>
<%
}
}
%>
</table>
</body>
</html>
messageSub.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.util.*,model.*" %>
<%
String title = request.getParameter("title");
String content = request.getParameter("content");
Message message = new Message();
message.setTitle(title);
message.setContent(content);
List<Message> messages = (List<Message>)session.getAttribute("messages");
if(messages == null){
messages = new ArrayList<Message>();
session.setAttribute("messages", messages);
}
messages.add(message);//留言列表信息存储至session中
response.sendRedirect(request.getContextPath()+"/message.jsp?subFlag=1");//重定向至留言板页面
%>
过滤器中filter-mapping子元素dispatcher配置
<filter>
<filter-name>testFilter</filter-name>
<filter-class>filter.TestFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>testFilter</filter-name>
<url-pattern>/test2.jsp</url-pattern>
<dispatcher>REQUEST</dispatcher><!--默认-->
<!--<dispatcher>FORWARD</dispatcher> -->
<!--<dispatcher>INCLUDE</dispatcher> -->
<!--<dispatcher>ERROR</dispatcher> -->
</filter-mapping>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%
//request.getRequestDispatcher("/test2.jsp").forward(request, response);//测试dispatcher FORWARD配置
//response.sendError(404);//测试dispatcher ERROR配置
%>
<!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=ISO-8859-1">
<title>Test1</title>
</head>
<body>
<!-- 测试dispatcher INCLUDE配置 -->
<!--<jsp:include page="test2.jsp"></jsp:include>-->
<h1>Test1</h1>
</body>
</html>