1、什么是过滤器
filter是对客户端访问资源的过滤,符合条件放行,不符合条件不放行,并且可以对目标资源访问前后进行逻辑处理。
2、filter生命周期及其与生命周期相关的方法
Filter接口有三个方法,并且这个三个都是与Filter的生命相关的方法
init(Filterconfig):代表filter对象初始化方法 filter对象创建时执行
doFilter方法
doFilter(ServletRequest,ServletResponse,FilterChain)
其中的参数:
ServletRequest/ServletResponse:每次在执行doFilter方法时 web容器负责创建一个request和一个response对象作为doFilter的参数传递进来。该request个该response就是在访问目标资源的service方法时的request和response。
FilterChain:过滤器链对象,通过该对象的doFilter方法可以放行该请求
destory():代表是filter销毁方法 当filter对象销毁时执行该方法
Filter对象的生命周期:
Filter何时创建:服务器启动时就创建该filter对象
Filter何时销毁:服务器关闭时filter销毁
3、过滤器代码示例
Servlet1.java
package cn.ctgu.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;
/**
* Servlet implementation class Servlet1
*/
@WebServlet("/Servlet1")
public class Servlet1 extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().write("Servlet1 running......");
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
package cn.ctgu.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="QuickFilter",urlPatterns="/*")
public class QuickFilter implements Filter{
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
System.out.println("quick1 running......");
//放行请求,但还是先执行quick1 running...... 然后执行客户端的请求
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
4、过滤器案例
4.1 自动登录
login.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>
<div>
<form action="${pageContext.request.contextPath }/LoginServlet" method="post">
用户名:<input type="text" name="username"/><br/>
密码:<input type="password" name="password"/><br/>
自动登陆:<input type="checkbox" name="auto" value="autoLogin"/><br/>
<!-- 记住用户名:<input type="checkbox" name="remembername"/><br/> -->
<input type="submit" name="submit" value="登录"/>
</form>
</div>
<div>
<span style="color:red">${loginInfo }</span>
</div>
</body>
</html>
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
asdfadfaf
</body>
</html>
LoginServlet.java
package cn.ctgu.servlet;
import java.io.IOException;
import java.net.URLDecoder;
import java.sql.SQLException;
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 javax.servlet.http.HttpSession;
import org.apache.catalina.util.URLEncoder;
import cn.ctgu.domain.User;
import cn.ctgu.service.UserService;
/**
* Servlet implementation class LoginServlet
*/
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
HttpSession session=request.getSession();
//获取数据
String username=request.getParameter("username");//获取中文张三
String password=request.getParameter("password");
UserService service=new UserService();
User user=null;
try {
user=service.login(username,password);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//登陆成功
if(user!=null) {
//登陆成功
//判断用户是否勾选自动登陆
String autoLogin=request.getParameter("autoLogin");
if(autoLogin!=null) {
//对中文张三进行编码
String username_code=java.net.URLEncoder.encode(username, "utf-8");
Cookie cookie_username=new Cookie("cookie_username", username_code);
Cookie cookie_password=new Cookie("cookie_password", user.getPassword());
//设置cookie的持久化时间
cookie_username.setMaxAge(60*60);
cookie_password.setMaxAge(60*60);
//设置cookie的携带路径
cookie_username.setPath(request.getContextPath());
cookie_username.setPath(request.getContextPath());
//发送cookie
response.addCookie(cookie_username);
response.addCookie(cookie_password);
}
//将登陆的用户的user对象存到session中
session.setAttribute("user", user);
//重定向到首页
response.sendRedirect("index.html");
}else {
//失败 转发到登陆页面 提示信息
request.setAttribute("loginInfo", "用户名或 密码错误");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
AutoLoginFilter.java
package cn.ctgu.filter;
import java.io.IOException;
import java.net.URLDecoder;
import java.sql.SQLException;
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 javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import cn.ctgu.domain.User;
import cn.ctgu.service.UserService;
//@WebFilter(filterName="AutoLoginFilter",urlPatterns="/*")
public class AutoLoginFilter implements Filter{
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req=(HttpServletRequest)request;
HttpServletResponse resq=(HttpServletResponse)response;
HttpSession session=req.getSession();
//获得cookie中用户名和密码 进行登陆的操作
//定义cookie_username
String cookie_username=null;
//定义cookie_password
String cookie_password=null;
//获得cookie
Cookie[]cookies=req.getCookies();
if(cookies!=null) {
for(Cookie cookie:cookies) {
//获得名字是cookie_username和cookie_password
if("cookie_username".equals(cookie.getName())) {
cookie_username=cookie.getValue();
//恢复中文用户名
cookie_username=URLDecoder.decode(cookie_username, "utf-8");
}
if("cookie_password".equals(cookie.getName())) {
cookie_password=cookie.getValue();
}
}
}
//判断username和password是否是null
if(cookie_username!=null&&cookie_password!=null) {
//登陆代码
UserService service=new UserService();
User user=null;
try {
user=service.login(cookie_username,cookie_password);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//将登陆的用户的user对象存到session中
session.setAttribute("user", user);
}
//放行
chain.doFilter(req, resq);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
User.java
package cn.ctgu.domain;
public class User {
private String username;
private String password;
private int id;
private String email;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
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;
}
public User() {
super();
// TODO Auto-generated constructor stub
}
}
JDBCUtilsConfig.java
package cn.ctgu.dao;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;
/*
* 编写JDBC的工具类,获取数据库的连接对象采用
* 采用读取配置文件的方式
* 读取文件获取连接,执行一次,采用static代码块,
*
* */
public class JDBCUtilsConfig {
private static Connection con;
private static String driverClass;
private static String url;
private static String username;
private static String password;
static {
try {
readConfig();
Class.forName(driverClass);
con=DriverManager.getConnection(url, username, password);
}catch(Exception e) {
throw new RuntimeException("数据库连接失败");
}
}
private static void readConfig() throws Exception{
InputStream in=JDBCUtilsConfig.class.getClassLoader().getResourceAsStream("database.properties");
Properties pro=new Properties();
pro.load(in);
driverClass=pro.getProperty("driverClass");
url=pro.getProperty("url");
username=pro.getProperty("username");
password=pro.getProperty("password");
}
public static Connection getConnection() {
return con;
}
}
UserService.java
package cn.ctgu.service;
import java.sql.SQLException;
import cn.ctgu.dao.UserDao;
import cn.ctgu.domain.User;
public class UserService {
public User login(String username, String password) throws SQLException {
// TODO Auto-generated method stub
UserDao dao=new UserDao();
return dao.login(username,password);
}
}
4.2 解决全局乱码问题
encoding.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>解决全局乱码</title>
</head>
<body>
<form action="${pageContext.request.contextPath }/encodingServlet" method="post">
<input type="text" name="username"/>
<input type="submit" value="提交">
</form>
</body>
</html>
encodingServlet.java
package cn.ctgu.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;
/**
* Servlet implementation class encodingServlet
*/
@WebServlet("/encodingServlet")
public class encodingServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String parameter=request.getParameter("username");
System.out.println(parameter);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
encodingFilter.java
package cn.ctgu.filter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
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.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
@WebFilter(filterName="encodingFilter",urlPatterns="/*")
public class encodingFilter implements Filter{
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
//request.setCharacterEncoding("utf-8");
//在传递request之前对request的getParameter方法进行增强
/*
* 装饰者模式增强
* 1、增强类与被增强类要实现统一接口
* 2、在增强类中传入被增强的类
* 3、需要增强的方法重写 不需要增强的方法调用被增强对象的
*
*
* */
//被增强的对象
HttpServletRequest req=(HttpServletRequest)request;
//增强对象
EnhanceRequest enhanceRequest=new EnhanceRequest(req);
chain.doFilter(enhanceRequest, response);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
class EnhanceRequest extends HttpServletRequestWrapper{
private HttpServletRequest request;
public EnhanceRequest(HttpServletRequest request) {
super(request);
this.request=request;
}
//对getParameter增强
@Override
public String getParameter(String name) {
String parameter=request.getParameter(name);//乱码
try {
parameter=new String(parameter.getBytes("iso8859-1"),"utf-8");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return parameter;
}
}
4.3 Filter的配置
url-pattern配置时
1)完全匹配 /sertvle1
2)目录匹配 /aaa/bbb/* —-最多的
/user/*:访问前台的资源进入此过滤器
/admin/*:访问后台的资源时执行此过滤器
3)扩展名匹配 .abc .jsp
注意:url-pattern可以使用servlet-name替代,也可以混用
dispatcher:访问的方式(了解)
REQUEST:默认值,代表直接访问某个资源时执行filter
FORWARD:转发时才执行filter
INCLUDE: 包含资源时执行filter
ERROR:发生错误时 进行跳转是执行filter
总结Filter的作用:
1)公共代码的提取
2)可以对request和response中的方法进行增强(装饰者模式/动态代理)
进行权限控制