Filter
过滤器 : 其实就是对客户端发出来的请求进行过滤。 浏览器发出, 然后服务器派servlet处理。 在中间就可以过滤, 其实过滤器起到的是拦截的作用。
作用:
- 对一些敏感词汇进行过滤
- 统一设置编码
- 自动登录
如何使用Filter:
1. 定义一个类, 实现Filter
/**
* 过滤器简单测试
*/
public class FilterDemo implements Filter {
//销毁方法
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//客户端请求过来走这块
System.out.println("过滤了");
//放行方法
chain.doFilter(request, response);
//服务器回去走这块
}
//初始化方法
public void init(FilterConfig fConfig) throws ServletException {
}
}
2. 注册过滤器
在web.xml里面注册,注册的手法与servlet基本一样
<filter>
<display-name>FilterDemo</display-name>
<filter-name>FilterDemo</filter-name>
<filter-class>it.cast.filter.FilterDemo</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterDemo</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Filter的生命周期
过滤器生命周期:
Filter执行顺序 :
- 创建: 服务器加载这个项目的时候创建实例
- 销毁: 关闭服务器或者从服务器中移除项目的时候
1. 客户端发出请求,先经过过滤器, 如果过滤器放行,那么才能到servlet
2. 如果有多个过滤器, 那么他们会按照注册的映射顺序【<filter-mapping>】 来 排队。 只要有一个过滤器, 不放行,那么后面排队的过滤器以及咱们的servlet都不会收到请求。
Filter细节:
1. init方法的参数 FilterConfig , 可以用于获取filter在注册的名字 以及初始化参数。 其实这里的设计的初衷与ServletConfig是一样的。
2. 如果想放行,那么在doFilter 方法里面操作,使用参数 chain
chain.doFilter(request, response); 放行, 让请求到达下一个目标。
3. <url-pattern>/*</url-pattern> 写法格式与servlet一样。
1. 全路径匹配 以 / 开始
/LoginServlet
2. 以目录匹配 以 / 开始 以 * 结束
/demo01/*
3. 以后缀名匹配 以 * 开始 以后缀名结束
*.jsp *.html *.do
4. 针对 dispatcher 设置【<filter-mapping>里面】
REQUEST : 只要是请求过来,都拦截,默认就是REQUEST
FORWARD : 只要是转发都拦截。
ERROR : 页面出错发生跳转 拦截
INCLUDE : 包含页面的时候就拦截。
自动登录
项目名:AutoLoginDemo
需求:
1.用户第一次访问登录页面,服务器处理请求,检验用户名和密码。校验失败跳转到登录页;校验成功,完成登录,存储账号和密码到cookie,发送cookie到客户端,使用session来存储用户信息,页面跳转到主页,显示【您好,欢迎您登录,用户名】。
2.当用户直接访问主页时,过滤器分为2种处理情况:
- 本次会话的session还存在,表明还在当前登录状态,放行,直接跳转主页,显示【您好,欢迎您登录,用户名】;
- 本次会话的session失效,检查浏览器访问请求带来的cookie。若有cookie,则帮助用户完成登录,使用session来存储用户信息,放行,跳转主页,显示【您好,欢迎您登录,用户名】。没有cookie则表示没有登录,放行,跳转到主页,显示【请您去登录!】
代码:
数据库:
登录页面:login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="LoginServlet" method="post">
用户名:<input type="text" name="username"><br>
密码: <input type="password" name="password"><br>
<input type="checkbox" name="anto_login">自动登录<br>
<input type="submit" value="登录">
</form>
</body>
</html>
首页:index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
这是首页,
<c:if test="${not empty userBean }">
您好,欢迎您登录:${userBean.username }
</c:if>
<c:if test="${empty userBean }">
请您去登录!
</c:if>
</body>
</html>
bean:UserBean
public class UserBean {
private int id;
private String username;
private String password;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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;
}
}
UserDao:
public interface UserDao {
/**
* 用户登录
* @param user 登录的用户信息
* @return 用户的数据
*/
UserBean login(UserBean user)throws SQLException ;
}
UserDaoImpl:
public class UserDaoImpl implements UserDao {
public UserBean login(UserBean user) throws SQLException {
QueryRunner runner=new QueryRunner(JDBCUtil.getDataSource());
String sql="select * from t_suer where username=? and password=?";
return runner.query(sql, new BeanHandler<UserBean>(UserBean.class),user.getUsername(),user.getPassword() );
}
}
负责处理登录页面的Servlet:
public class LoginServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
//1.取值
String username = request.getParameter("username");
String password = request.getParameter("password");
String anto_login = request.getParameter("anto_login");
//2.把值封装成Userbean对象
UserBean user=new UserBean();
user.setUsername(username);
user.setPassword(password);
//3.数据库查询
UserDao dao=new UserDaoImpl();
UserBean userBean = dao.login(user);
//判断
if(userBean!=null) {
//说明用户名和密码正确
if("on".equals(anto_login)) {
//勾选了自动登录
Cookie cookie=new Cookie("anto_login", username+"#"+password);
cookie.setMaxAge(60*60*24*7);//设置生存期限为1天
cookie.setPath("/AutoLoginDemo");
response.addCookie(cookie);
}
//保存到session里面,并且跳转到首页index.jsp
request.getSession().setAttribute("userBean", userBean);
response.sendRedirect("index.jsp");
}else {
//用户名或密码错误,跳转到登录页
request.getRequestDispatcher("login.jsp").forward(request, response);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
过滤器:AutoFilter
public class AutoFilter implements Filter {
public void destroy() {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest req, ServletResponse response, FilterChain chain) throws IOException, ServletException {
try {
HttpServletRequest request=(HttpServletRequest) req;
//1.获取session
UserBean userBean=(UserBean) request.getSession().getAttribute("userBean");
if (userBean!=null) {
//userBean还存在,说明本次会话还没结束,用户还在登录状态,直接放行
chain.doFilter(request, response);
} else {
//2.会话结束,session失效了,获取Cookie里面的值
Cookie[] cookies = request.getCookies();
//从一堆的cookie里面找出我们以前给浏览器发的那个cookie
Cookie cookie = CookieUtil.findCookie(cookies, "anto_login");
if (cookie==null) {
//说明是第一次登录,直接放行
chain.doFilter(request, response);
}else {
//3.说明不是第一次登录,设置自动登录
String username = cookie.getValue().split("#")[0];
String password = cookie.getValue().split("#")[1];
//封装值到bean里面
UserBean user=new UserBean();
user.setUsername(username);
user.setPassword(password);
//查询数据库
UserDao dao=new UserDaoImpl();
userBean = dao.login(user);
//把bean存到session中,方便下一次未过期前还可以用。
request.getSession().setAttribute("userBean", userBean);
chain.doFilter(req, response);
}
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
chain.doFilter(req, response);
}
}
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
过滤器配置文件:
<filter>
<display-name>AutoFilter</display-name>
<filter-name>AutoFilter</filter-name>
<filter-class>it.cast.filter.AutoFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>AutoFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
工具类:
用于获取特定cookie的工具类:
public class CookieUtil {
public static Cookie findCookie(Cookie[]cookies,String key ) {
if (cookies!=null) {
for (Cookie cookie : cookies) {
if(key.equals(cookie.getName()))
return cookie;
}
}
return null;
}
}
数据库的工具类:
/**
* 使用C3P0改写的JDBCUtil工具类
*/
public class JDBCUtil {
static ComboPooledDataSource dataSource=null;
static {
dataSource=new ComboPooledDataSource();
}
/**
* 因为要使用dbutil,所以要获取DataSource对象
* @return DataSource对象
*/
public static DataSource getDataSource() {
return dataSource;
}
/*
* jabc的连接
*/
public static Connection jdbcConn() throws SQLException {
return dataSource.getConnection();
}
/*
* 关闭数据库的方法,释放资源
*/
public static void resease(ResultSet rs,Statement st,Connection conn) {
rsclose(rs);
stclose(st);
connclose(conn);
}
public static void resease(Statement st,Connection conn) {
stclose(st);
connclose(conn);
}
private static void rsclose(ResultSet rs) {
try {
if(rs!=null)
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
private static void stclose(Statement st) {
try {
if(st!=null)
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
private static void connclose(Connection conn) {
try {
if(conn!=null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
c3p0配置:
c3p0-config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<property name="jdbcUrl">jdbc:mysql://localhost/stus</property>
<property name="user">root</property>
<property name="password">19930903</property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="initialPoolSize">10</property>
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">100</property>
<property name="minPoolSize">10</property>
<property name="maxStatements">200</property>
</default-config>
</c3p0-config>