一:过滤器概述:
- 组成:
过滤源(用户请求request)——>过滤规则(即Java代码要实现的效果)——>过滤结果 - 定义:
过滤器是一个【服务器端】的组件,它可以【截取用户端的请求和响应信息】,并对这些信息过滤。
Web过滤器不是用来处理请求的,而是用来做一些辅助性的操作。 - 生命周期:
1.在web容器启动时依据web.xml实例化 一次
2.初始化 init() 一次
3.过滤 doFilter() 多次
4.销毁 destroy() 一次 ,web容器关闭 - 分类:
- REQUEST:默认的过滤器(我们配置过滤器默认选择的),用户直接访问页面时,Web容器将会调用过滤器,通过链接访问直接到达过滤器。
- FORWARD:目标资源是通过RequestDispatcher的forward访问时,该过滤器被调用。<dispatcher>FORWARD</dispatcher>
重定向:会使用REQUEST过滤器,response.sendRedirect(request.getContextPath() + “/main.jsp”);
转发:会使用FORWARD过滤器,request.getRequestDispatcher(“main.jsp”).forward(request, response);- INCLUDE:目标资源时通过RequestDispatcher的include方法调用时,过滤器将被调用。<dispatcher>INCLUDE</dispatcher>
- ERROR:用户访问页面或者服务器出错时提示的错误页面,常见的是404页面。
- 补充:Error过滤器的两种使用方式:
1.@web.xml配置文件
<!-- 配置错误页面的跳转-->
<error-page>
<error-code>404</error-code>
<location>/errorPage.jsp</location>
</error-page>
<!-- 当访问到错误页面时的过滤器配置 -->
<filter>
<filter-name>errorTest</filter-name>
<filter-class>com.minGe.Filter.FilterTest03</filter-class>
</filter>
<filter-mapping>
<filter-name>errorTest</filter-name>
<url-pattern>/errorPage.jsp</url-pattern>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
2.注解:
@WebFilter(filterName="errorTest",value= {"/errorPage.jsp"},dispatcherTypes= {DispatcherType.ERROR})
public class FilterTest03 implements Filter{
@Override
public void destroy() {
System.out.println("start...run...errorPage...destroy");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("start...run...errorPage...doFilter");
chain.doFilter(request, response);
System.out.println("end...run...errorPage...doFilter");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("start...run...errorPage...init");
}
}
二:登录案例实现:
- 实现功能描述
- 1)基本功能:用户进入登录(login.jsp)页面,输入用户名密码,经后台检测后结果正确则跳转到success.jsp页面并且将用户信息保存进session域;结果不正确则进入fail.jsp页面。
- 2)加入过滤器功能:若用户不经login页面录入登录信息直接访问success.jsp页面,过滤器截取到用户请求后检测session域中是否有用户信息(登录成功后先往session中存入用户信息),若没有说明用户并未登录,不可以访问success.jsp页面,过滤器将重定向到login.jsp页面让用户登录。
- 3)设置不被过滤器过滤的页面:过滤器将会对所有的页面进行过滤,但是fail.jsp页面和login.jsp页面不需要过滤,允许用户不经登录直接访问,所以要通过程序将这两个页面从过滤器中排除。
- 步骤:
1.新建Dynamic Web Project
2.新建jsp页面
3.配置过滤器
4.新建servlet
5.新建filter
- 代码如下:
@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>JavaFilterTest</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 登陆页面的servlet -->
<servlet>
<!-- 自定义servlet名称 -->
<servlet-name>loginServlet</servlet-name>
<!-- loginServlet对应的具体的servlet类 -->
<servlet-class>com.minGe.Servlet.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<!-- 映射到哪一个servlet标签中的servlet-name -->
<servlet-name>loginServlet</servlet-name>
<!-- 触发该servlet的请求 -->
<url-pattern>/loginServlet.do</url-pattern>
</servlet-mapping>
<!-- 登陆页面的过滤器 -->
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>com.minGe.Filter.LoginFilter</filter-class>
<!-- 一些过滤器的初始化参数 -->
<init-param>
<!--
同过滤器(LoginFilter)的init中的FilterConfig配合使用,可以让过滤器不截取param-value标签配置的页面的客户端请求。
param-name:名称,通过config.getInitParameter("noLoginPaths")获取页面参数
param-value:页面
-->
<param-name>noLoginPaths</param-name>
<param-value>login.jsp;fail.jsp;loginServlet.do</param-value>
</init-param>
</filter>
<!-- 访问/*(所有页面)的请求都映射到LoginFilter对应的过滤器类中 -->
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<!-- 对所有的页面都要做过滤,包括fail和login页面(但是这两个页面不需要过滤,直接访问即可) -->
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
@login.jsp
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Login</title>
</head>
<body>
<h1>Login.jsp</h1>
<form action="<%=request.getContextPath()%>/loginServlet.do" method="post">
UserName:<input type="text" name="username" placeholder="Please Input"/><br>
Password:<input type="password" name="password" placeholder="Please Input"/><br>
<button>Submit</button>
</form>
</body>
</html>
@success.jsp
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>success</title>
</head>
<body>
<h1>Welcome ${username}</h1>
</body>
</html>
@fail.jsp
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>fail</title>
</head>
<body>
<h1>用户名或密码输入错误</h1>
</body>
</html>
@LoginServlet
package com.minGe.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;
import javax.servlet.http.HttpSession;
/**
* Servlet implementation class LoginServlet
*/
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
System.out.println("用户名:"+username);
System.out.println("密码:"+password);
//模拟数据库操作,用户名密码正确则进入success页面,否则进入错误页面
if("admin".equals(username)&&"admin".equals(password)) {
HttpSession session = request.getSession();
session.setAttribute("username", username);
response.sendRedirect(request.getContextPath()+"/success.jsp");
}else {
System.out.println("用户名和密码错误");
response.sendRedirect(request.getContextPath()+"/fail.jsp");
}
}
}
@LoginFilter
package com.minGe.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;
import javax.servlet.http.HttpSession;
public class LoginFilter implements Filter{
private FilterConfig config;
@Override
public void destroy() {
System.out.println("start...run...LoginFilter...destroy");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
//过滤器截取到页面请求后做的操作。
System.out.println("start...run...LoginFilter...doFilter");
//强制转换request的类型为HttpServletRequest(不同的类有不同的方法)
HttpServletRequest requ = (HttpServletRequest) request;
//强制转换response的类型为HttpServletResponse
HttpServletResponse respon = (HttpServletResponse) response;
//通过requ获取session
HttpSession session = requ.getSession();
//获取的是web.xml中filter过滤器配置中的init-param标签下的初始化信息
String noLoginPaths = config.getInitParameter("noLoginPaths");
//打印结果:login.jsp;loginServlet.do,同上面解释对应
System.out.println(noLoginPaths);
System.out.println(requ.getRequestURI());
//不为空则执行,即如果设置了不经过过滤器的页面,则在方法下面做具体的操作
if(noLoginPaths!=null) {
//按照“;”将页面信息分割开来保存进数组
String[] strArr = noLoginPaths.split(";");
for (String string : strArr) {
if(string == null || "".equals(string))continue;
//页面请求带过来的信息
//即如果要访问的页面是noLoginPaths配置中的一个,则无需过滤器过滤,直接通过。
if(requ.getRequestURI().indexOf(string)!=-1) {
chain.doFilter(request, response);
return;
}
}
}
/***
* 判断session域中是否有username的信息,
* 如果有说明用户已经登录过,可以进入success页面,
* 如果没有则跳转到登陆页面让用户登录
*/
if(session.getAttribute("username")!=null) {
chain.doFilter(request, response);
}else {
respon.sendRedirect(requ.getContextPath()+"/login.jsp");
}
//过滤器收到服务器返回的请求之后所作的操作。
System.out.println("end...run...LoginFilter...doFilter");
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("start...run...LoginFilter...init");
//在web.xml初始化时将filterConfig赋值给自定义的config,以便后期获取web.xml中的filter初始配置信息。
config = filterConfig;
//打印结果:ApplicationFilterConfig[name=LoginFilter, filterClass=com.minGe.Filter.LoginFilter]
//System.out.println(config);
}
}