1.Filter过滤器
1.什么是Filter
2.实现第一个Filter程序
1.在eclipse中创建一个chapter08的Web项目,然后在项目的src目录下创建一个cn.itcast.chapter08.filter的包,在此包下创建一个MyServlet的Servlet类,用于访问时在浏览器中输出“HelloMyServlet”,实现代码如下:
package cn.itcast.chapter08.filter;
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 {
response.getWriter().write("Hello MyServlet");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
2.在web.xml文件中对Servlet进行配置
<servlet>
<display-name>MyServlet</display-name>
<servlet-name>MyServlet</servlet-name>
<servlet-class>cn.itcast.chapter08.filter.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/MyServlet</url-pattern>
</servlet-mapping>
启动Tomcat服务器,在地址栏输入“http://localhost:2222/chapter08/myservlet”,运行结果如下:
3.在cn.itcast.chapter08.filter包中创建一个MyFilter的Filter类,用于拦截Servlet程序,代码如下:
package cn.itcast.chapter08.filter;
import java.io.IOException;
import java.io.PrintWriter;
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("/myfilter")
public class MyFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
response.setContentType("text/html;charset=utf-8");
System.out.println("输出内容表示拦截了响应");
response.getWriter().print("这是filter输出到网页的内容");
if (true) {
chain.doFilter(request, response);
}
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
同样的,在web.xml文件中配置信息,如下:
<filter>
<display-name>MyFilter</display-name>
<filter-name>MyFilter</filter-name>
<filter-class>cn.itcast.chapter08.filter.MyFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/MyServlet</url-pattern>
</filter-mapping>
重启Tomcat服务器,在地址栏输入“http://localhost:2222/chapter08/myservlet”,运行结果如下:
3.Filter映射
3.1 在chapter08项目的cn.itcast.chapter08.filter包中创建一个ForwardServlet的Servlet类,用于将请求转发给first.jsp页面,如下所示:
package cn.itcast.chapter08.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("/forward")
public class ForwardServlet implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.getRequestDispatcher("/first.jsp").forward(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
3.2 在web.xml文件中,配置ForwardServlet信息,如下:
<servlet>
<servlet-name>ForwardServlet</servlet-name>
<servlet-class>cn.itcast.chapter08.filter.ForwardServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ForwardServlet</servlet-name>
<url-pattern>/ForwardServlet</url-pattern>
</servlet-mapping>
3.3在chapter08项目的WebContent目录中创建一个first.jsp页面,用于输出内容,如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
first.jsp
</body>
</html>
3.4在cn.itcast.chapter08.filter的包中创建一个过滤器ForwardFilter.java,用于对first.jsp页面进行拦截,如下:
package cn.itcast.chapter08.filter;
import java.io.IOException;
import java.io.PrintWriter;
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("/forwardFilter")
public class ForwardFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
PrintWriter out = response.getWriter();
out.write("Hello FilterTest");
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
3.5在web.xml文件中,配置过滤器的映射信息,拦截first.jsp页面
<filter>
<filter-name>ForwardFilter</filter-name>
<filter-class>cn.itcast.chapter08.filter.ForwardFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ForwardFilter</filter-name>
<url-pattern>/first.jsp</url-pattern>
</filter-mapping>
3.6启动Tomcat服务器,运行结果如下:
3.7 在web.xml文件中添加一个<dispatcher>子元素,将该元素的值设置为FORWARD,修改后的ForwardFilter的映射如下:
<filter>
<filter-name>ForwardFilter</filter-name>
<filter-class>cn.itcast.chapter08.filter.ForwardFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ForwardFilter</filter-name>
<url-pattern>/first.jsp</url-pattern>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
3.8 重启Tomcat服务器,运行结果如图:
4.Filter 链
4.1在chapter08项目的cn.itcast.chapter08.filter包中创建两个过滤器MyFilter01和MyFilter02,如下:
MyFilter01:
package cn.itcast.chapter08.filter;
import java.io.IOException;
import java.io.PrintWriter;
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("/myfilter01")
public class MyFilter01 implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
PrintWriter out=response.getWriter();
out.write("hello Myfilter01<br/>");
chain.doFilter(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
MyFilter02:
package cn.itcast.chapter08.filter;
import java.io.IOException;
import java.io.PrintWriter;
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("/myfilter02")
public class MyFilter02 implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
PrintWriter out=response.getWriter();
out.write(" Myfilter02---------before<br/>");
chain.doFilter(request, response);
out.write(" <br/>Myfilter02---------after<br/>");
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
4.2将web.xml文件中其他配置信息注释,然后再在web.xml文件中写入MyFilter01和MyFilter02过滤器的映射配置信息在Servlet配置信息之前,配置信息如下:
<filter>
<filter-name>MyFilter01</filter-name>
<filter-class>cn.itcast.chapter08.filter.MyFilter01</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter01</filter-name>
<url-pattern>/MyServlet</url-pattern>
</filter-mapping>
<filter>
<filter-name>MyFilter02</filter-name>
<filter-class>cn.itcast.chapter08.filter.MyFilter02</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter02</filter-name>
<url-pattern>/MyServlet</url-pattern>
</filter-mapping>
<servlet>
<display-name>MyServlet</display-name>
<servlet-name>MyServlet</servlet-name>
<servlet-class>cn.itcast.chapter08.filter.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/MyServlet</url-pattern>
</servlet-mapping>
5.FilterConfig接口
5.1 在chapter08项目的cn.itcast.chapter08.filter包中创建过滤器MyFilter03,使用该过滤器来获取web.xml中设置的参数,代码如下:
package cn.itcast.chapter08.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("/myfilter03")
public class MyFilter03 implements Filter {
private String characterEncoding;
FilterConfig fc;
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
characterEncoding = fc.getInitParameter("encoding");
System.out.println("encoding初始参数的值为:"+characterEncoding);
chain.doFilter(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {
this.fc=fConfig;
}
@Override
public void destroy() {
}
}
5.2 在web.xml文件中配置过滤器信息,将此条映射配置信息放置在web.xml文件最前端,如下:
<filter>
<filter-name>MyFilter03</filter-name>
<filter-class>cn.itcast.chapter08.filter.MyFilter03</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>GBK</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>MyFilter03</filter-name>
<url-pattern>/MyServlet</url-pattern>
</filter-mapping>
启动Tomcat服务器,运行结果如下所示:
2.使用Filter实现用户自动登录
1.编写User类
在chapter08项目中创建一个叫cn.itcast.chapter08.entity的包,在该包中编写一个User类,用于封装用户信息,如下:
package cn.itcast.chapter08.entity;
public class User{
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
2.实现登录页面及首页
2.1 在chapter08项目的WebContent中,编写login.jsp页面,用于创建一个用户登录的表单,表单中需填写用户名和密码,及用户自动登录的时间,如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8" import="java.util.*"%>
<html>
<head></head>
<center><h3>用户登录</h3></center>
<body style="text-align: center;">
<form action="${pageContext.request.contextPath }/LoginServlet"
method="post">
<table border="1" width="600px" cellpadding="0" cellspacing="0"
align="center" >
<tr>
<td height="30" align="center">用户名:</td>
<td>
<input type="text" name="username" />${errorMsg }</td>
</tr>
<tr>
<td height="30" align="center">密 码:</td>
<td>
<input type="password" name="password" /></td>
</tr>
<tr>
<td height="35" align="center">自动登录时间</td>
<td><input type="radio" name="autologin"
value="${60*60*24*31 }" />一个月
<input type="radio" name="autologin"
value="${60*60*24*31*3 }" />三个月
<input type="radio" name="autologin"
value="${60*60*24*31*6 }" />半年
<input type="radio" name="autologin"
value="${60*60*24*31*12 }" />一年
</td>
</tr>
<tr>
<td height="30" colspan="2" align="center">
<input type="submit" value="登录" />
<input type="reset" value="重置" />
</td>
</tr>
</table>
</form>
</body>
<html>
2.2 在chapter08项目的WebContent中,编写index.jsp页面,用于显示用户的登录信息,如果没有用户登录,则遭index.jsp页面中就显示一个超链接,如果用户已经登录,则显示用户登录的用户名,以及一个注销的超链接,如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8" import="java.util.*"
%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<title>显示登录的用户信息</title>
</head>
<body>
<br />
<center>
<h3>欢迎光临</h3>
</center>
<br />
<c:choose>
<c:when test="${sessionScope.user==null }">
<a href="http://localhost:2222/chapter08/login.jsp">用户登录</a>
</c:when>
<c:otherwise>
贵州欢迎您,${sessionScope.user.username} <a href="http://localhost:2222/chapter08/logout">退出</a>
</c:otherwise>
</c:choose>
<hr />
</body>
</html>
注:在上面的jsp文件中使用了JSTL标签库,因此项目中的lib中应添加JSTL标签库的支持jar包(jstl.jar和standard.jar)。
3.创建Servlet
3.1编写LoginServlet类
在chapter08项目的cn.itcast.chapter08.filter包中,编写LoginServlet类,用于处理用户的登录请求,若输入的用户名和密码正确,则发送一个用户自动登录的Cookie,并跳转到首页,否则会提示输入的用户名和密码错误,并跳转至登录页面login.jsp让用户重新登录,如下:
package cn.itcast.chapter08.filter;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.itcast.chapter08.entity.User;
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username=request.getParameter("username");
String password=request.getParameter("password");
if("itcast".equals(username)&&"123456".equals(password)) {
User user=new User();
user.setUsername(username);
user.setPassword(password);
request.getSession().setAttribute("uesr", user);
String autoLogin=request.getParameter("autoLogin");
if(autoLogin!=null) {
Cookie cookie=new Cookie("autoLogin", username+"-"+password);
cookie.setMaxAge(Integer.parseInt(autoLogin));
cookie.setPath(request.getContextPath());
response.addCookie(cookie);
}
response.sendRedirect(request.getContextPath()+"/index.jsp");
}else {
request.setAttribute("errerMsg", "用户名或密码错误");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
3.2编写LogoutServlet类
在chapter08项目的cn.itcast.chapter08.filter包中,编写LogoutServlet类,用于注销用户登录的信息,此程序中首先会将Session会话中保存的User对象删除,然后再将自动登录的Cookie删除,最后跳转至index.jsp,如下:
package cn.itcast.chapter08.filter;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getSession().removeAttribute("user");
Cookie cookie=new Cookie("autologin", "msg");
cookie.setMaxAge(0);
cookie.setPath(request.getContextPath());
response.addCookie(cookie);
response.sendRedirect(request.getContextPath()+"/index.jsp");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
4.创建过滤器
在chapter08项目的cn.itcast.chapter08.filter包中,编写AutoLoginFilter类,用于拦截用户登录的访问请求,判断请求中是否包含用户自动登录的Cookie,若包含,则获取Cookie中的用户名和密码,并验证用户名和密码是否正确,若正确,则将用户的登录信息封装到User对象存入Session域中,完成用户自动登录,如下:
package cn.itcast.chapter08.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.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import cn.itcast.chapter08.entity.User;
@WebFilter("/auto")
public class AutoLoginFilter implements Filter {
public void destroy() {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//1.获取所以的cookie
HttpServletRequest req = (HttpServletRequest)request;
Cookie[] cs = req.getCookies();
//2.cookie,找到保存用户名和密码的那个cookie
String autoLogin=null;
for(int i = 0 ; cs != null && i<cs.length ; i++) {
String cookieName = cs[i].getName();
if("autoLogin".equals(cookieName)) {
//找到了保存用户名和密码的cookie
autoLogin = cs[i].getValue();
}
}
//3.如果获取到用户名密码不为空,实现自动登录
if(autoLogin!=null) {
//判断用户名和密码是否正确
String[] strs = autoLogin.split("-");
String username = strs[0];
String password = strs[1];
if("itcast".equals(username) && "123".equals(password)) {
//用户名和密码正确
User u = new User();
u.setUsername(username);
u.setPassword(password);
//在index.jsp主页面,会显示用户信息
req.getSession().setAttribute("user",u);
}
}
chain.doFilter(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
5.配置映射信息
在web.xml文件中,配置所有相关Servlet及AutoLoginFilter过滤器信息,由于拦截用户访问请求,则将过滤器<filter-mapping>元素拦截的路径设置为“/*”,如下:
<filter>
<filter-name>AutoLoginFilter</filter-name>
<filter-class>cn.itcast.chapter08.filter.AutoLoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AutoLoginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>cn.itcast.chapter08.filter.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/LoginServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>LogoutServlet</servlet-name>
<servlet-class>cn.itcast.chapter08.filter.LogoutServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LogoutServlet</servlet-name>
<url-pattern>/LogoutServlet</url-pattern>
</servlet-mapping>
6.启动服务器,运行项目