过滤器的生命周期:
1、实例化
通过web.xml配置,web容器启动时就会加载过滤器,实例化只会实例化一次。Servlet3.0规范中新增了@WebFilter的方式,这种方式用于讲一个类声明为过滤器,该注解将会在部署时被web容器处理,容器将根据具体的属性配置将相应的类部署为过滤器。
2、初始化
调用过滤器的init(),这是过滤器的初始化方法,web容器创建过滤器实例后将调用这个方法。这个方法中可以读取web.xml文件中过滤器的参数。
3、过滤方法
每次请求都会调用过滤器的doFilter(),这个方法完成实际的过滤操作。这个是过滤器的核心方法,当用户请求访问与过滤器关联的URL时,web容器将先调用过滤器的doFilter()。FilterChain参数可以调用chain.doFilter(),将请求传递给下一个过滤器(或目标资源),或利用转发,重定向将请求转发到其他资源。
4、销毁
当web容器在销毁过滤器实例前调用destroy(),在这个方法中可以释放过滤器占用的资源。
过滤器的分类:
指定过滤器的转发模式,对应filter中的dispatchTypes属性,具体属性值包括以下5个,其中Servlet2.5支持REQUEST、FORWARD、INCLUDE、ERROR,Servlet3.0新增ASYNC
1、REQUEST
用户直接访问页面时,web容器将会调用过滤器,过滤器的默认种类。
2、FORWARD
目标资源是通过RequestDispatch的forward访问时,该过滤器将被调用。
3、INCLUDE
目标资源是通过RequestDispatch的include访问时,该过滤器将被调用。
4、ERROR
目标资源是通过声明式异常处理机制调用时,过滤器将被调用。
5、ASYNC
支持异步处理
过滤器示例:
web.xml
login.jsp
success.jsp
failure.jsp
LoginServlet.java
LoginFilter.java
EncodingFilter.java
Servlet3.0特性:
Servlet3.0支持注解的方式注册servlet和filter,我们不需要在web.xml中配置servlet和filter,只需要在servlet和filter类中用@方式注入即可,代码如下:
LoginServlet.java
LoginFilter.java
EncodingFilter.java
LoginServlet.java
这样的配置等同web.xml中的配置
LoginFilter.java
这样的配置等同web.xml中的配置
EncodingFilter.java
这样的配置等同web.xml中的配置
Servlet3.0过滤器执行顺序:
Servlet3.0之前Filter过滤的顺序是由用户在web.xml中配置的顺序决定的,如我们的程序会先执行LoginFilter,再执行encodingFilter。
在3.0之后新增@WebFilter注解,当使用注解配置多个Filter时,用户无法控制其执行顺序,此时Filter过滤的顺序是按照Filter的类名来控制的,按自然排序的规则。LoginFilter.java 和 EncodingFilter.java 这两个文件里面分别是“用户登录过滤器”和“字符集过滤器”,因为这两个文件的首字母E排L之前,导致每次执行的时候都是先执行“字符集过滤器”再执行“用户登录过滤器”,所以我们现在修改两个文件的名称分别为
Filter0_EncodingFilter.java
Filter1_LoginFilter.java
这样就能先执行“用户登录过滤器”再执行“字符集过滤器”。
1、实例化
通过web.xml配置,web容器启动时就会加载过滤器,实例化只会实例化一次。Servlet3.0规范中新增了@WebFilter的方式,这种方式用于讲一个类声明为过滤器,该注解将会在部署时被web容器处理,容器将根据具体的属性配置将相应的类部署为过滤器。
2、初始化
调用过滤器的init(),这是过滤器的初始化方法,web容器创建过滤器实例后将调用这个方法。这个方法中可以读取web.xml文件中过滤器的参数。
3、过滤方法
每次请求都会调用过滤器的doFilter(),这个方法完成实际的过滤操作。这个是过滤器的核心方法,当用户请求访问与过滤器关联的URL时,web容器将先调用过滤器的doFilter()。FilterChain参数可以调用chain.doFilter(),将请求传递给下一个过滤器(或目标资源),或利用转发,重定向将请求转发到其他资源。
4、销毁
当web容器在销毁过滤器实例前调用destroy(),在这个方法中可以释放过滤器占用的资源。
过滤器的分类:
指定过滤器的转发模式,对应filter中的dispatchTypes属性,具体属性值包括以下5个,其中Servlet2.5支持REQUEST、FORWARD、INCLUDE、ERROR,Servlet3.0新增ASYNC
1、REQUEST
用户直接访问页面时,web容器将会调用过滤器,过滤器的默认种类。
2、FORWARD
目标资源是通过RequestDispatch的forward访问时,该过滤器将被调用。
3、INCLUDE
目标资源是通过RequestDispatch的include访问时,该过滤器将被调用。
4、ERROR
目标资源是通过声明式异常处理机制调用时,过滤器将被调用。
5、ASYNC
支持异步处理
过滤器示例:
web.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
- version="3.1">
- <filter>
- <filter-name>loginFilter</filter-name>
- <filter-class>com.pumpkin.filter.LoginFilter</filter-class>
- <init-param>
- <param-name>unfilteredPaths</param-name>
- <param-value>login.jsp;failure.jsp;login</param-value>
- </init-param>
- </filter>
- <filter>
- <filter-name>EncodingFilter</filter-name>
- <filter-class>com.pumpkin.filter.EncodingFilter</filter-class>
- <init-param>
- <param-name>charset</param-name>
- <param-value>UTF-8</param-value>
- </init-param>
- </filter>
- <filter-mapping>
- <filter-name>loginFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
- <filter-mapping>
- <filter-name>EncodingFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
- <servlet>
- <servlet-name>LoginServlet</servlet-name>
- <servlet-class>com.pumpkin.servlet.LoginServlet</servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>LoginServlet</servlet-name>
- <url-pattern>/login</url-pattern>
- </servlet-mapping>
- <welcome-file-list>
- <welcome-file>login.jsp</welcome-file>
- </welcome-file-list>
- </web-app>
login.jsp
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <html>
- <head>
- <title>Filter实例</title>
- </head>
- <body>
- <%
- System.out.println("===login.jsp===");
- %>
- <form action="login" method="post">
- 用户名:<input type="text" name="username"/>
- <br/>
- 密码:<input type="password" name="password"/>
- <br/>
- <input type="submit" value="提交"/>
- </form>
- </body>
- </html>
success.jsp
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <html>
- <head>
- <title>成功页面</title>
- </head>
- <body>
- <%
- System.out.println("===success.jsp===");
- %>
- ${username},登陆成功!
- </body>
- </html>
failure.jsp
- <%--
- Created by IntelliJ IDEA.
- User: Administrator
- Date: 2017/6/17
- Time: 22:47
- To change this template use File | Settings | File Templates.
- --%>
- <%@ page contentType="text/html;charset=UTF-8" language="java" %>
- <html>
- <head>
- <title>失败页面</title>
- </head>
- <body>
- <%
- System.out.println("===failure.jsp===");
- %>
- 登录失败!
- </body>
- </html>
LoginServlet.java
- package com.pumpkin.servlet;
- import javax.servlet.*;
- 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;
- import java.io.IOException;
- public class LoginServlet extends HttpServlet {
- public LoginServlet() {
- super();
- }
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- System.out.println("===LoginServlet===doGet===");
- doPost(req, resp);
- }
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- System.out.println("===LoginServlet===doPost===start===");
- String username = req.getParameter("username");
- String password = req.getParameter("password");
- System.out.println("===username===" + username + "===");
- if ("admin".equals(username) && "admin".equals(password)) {
- HttpSession session = req.getSession();
- session.setAttribute("username",username);
- resp.sendRedirect(req.getContextPath() + "/success.jsp");
- }else {
- resp.sendRedirect(req.getContextPath() + "/failure.jsp");
- }
- System.out.println("===LoginServlet===doPost===end===");
- }
- }
LoginFilter.java
- package com.pumpkin.filter;
- import javax.servlet.*;
- import javax.servlet.annotation.WebFilter;
- import javax.servlet.annotation.WebInitParam;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import javax.servlet.http.HttpSession;
- import java.io.IOException;
- import java.util.logging.Filter;
- public class LoginFilter implements javax.servlet.Filter {
- private FilterConfig config;
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {
- System.out.println("===LoginFilter===init===");
- config = filterConfig;
- }
- @Override
- public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
- System.out.println("===LoginFilter===doFilter===start===");
- HttpServletRequest request = (HttpServletRequest) servletRequest;
- HttpServletResponse response = (HttpServletResponse) servletResponse;
- HttpSession session = request.getSession();
- String unfilteredPaths = config.getInitParameter("unfilteredPaths");
- if (unfilteredPaths != null) {
- String[] strArray = unfilteredPaths.split(";");
- for (int i = 0; i < strArray.length; i++) {
- if (strArray[i] == null || "".equals(strArray[i])) {
- continue;
- }
- if (request.getRequestURI().indexOf(strArray[i]) != -1) {
- filterChain.doFilter(request, response);
- return;
- }
- }
- }
- if (session.getAttribute("username") != null) {
- filterChain.doFilter(request, response);
- } else {
- response.sendRedirect("login.jsp");
- }
- System.out.println("===LoginFilter===doFilter===end===");
- }
- @Override
- public void destroy() {
- System.out.println("===LoginFilter===destroy===");
- }
- }
EncodingFilter.java
- package com.pumpkin.filter;
- import com.sun.net.httpserver.Filter;
- import com.sun.net.httpserver.HttpExchange;
- import javax.servlet.*;
- import javax.servlet.annotation.WebFilter;
- import javax.servlet.annotation.WebInitParam;
- import java.io.IOException;
- public class EncodingFilter implements javax.servlet.Filter{
- private FilterConfig config;
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {
- System.out.println("===EncodingFilter===init===");
- config = filterConfig;
- }
- @Override
- public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
- System.out.println("===EncodingFilter===doFilter===start===");
- String charset = config.getInitParameter("charset");
- if (charset == null) {
- charset = "UTF-8";
- }
- servletRequest.setCharacterEncoding(charset);
- filterChain.doFilter(servletRequest,servletResponse);
- System.out.println("===EncodingFilter===doFilter===end===");
- }
- @Override
- public void destroy() {
- System.out.println("===EncodingFilter===destroy===");
- }
- }
Servlet3.0特性:
Servlet3.0支持注解的方式注册servlet和filter,我们不需要在web.xml中配置servlet和filter,只需要在servlet和filter类中用@方式注入即可,代码如下:
LoginServlet.java
- package com.pumpkin.servlet;
- import javax.servlet.*;
- 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;
- import java.io.IOException;
- @WebServlet(name = "LoginServlet",urlPatterns = "/login")
- public class LoginServlet extends HttpServlet {
- public LoginServlet() {
- super();
- }
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- System.out.println("===LoginServlet===doGet===");
- doPost(req, resp);
- }
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- System.out.println("===LoginServlet===doPost===start===");
- String username = req.getParameter("username");
- String password = req.getParameter("password");
- System.out.println("===username===" + username + "===");
- if ("admin".equals(username) && "admin".equals(password)) {
- HttpSession session = req.getSession();
- session.setAttribute("username",username);
- resp.sendRedirect(req.getContextPath() + "/success.jsp");
- }else {
- resp.sendRedirect(req.getContextPath() + "/failure.jsp");
- }
- System.out.println("===LoginServlet===doPost===end===");
- }
- }
LoginFilter.java
- package com.pumpkin.filter;
- import javax.servlet.*;
- import javax.servlet.annotation.WebFilter;
- import javax.servlet.annotation.WebInitParam;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import javax.servlet.http.HttpSession;
- import java.io.IOException;
- import java.util.logging.Filter;
- @WebFilter(filterName = "Filter1_LoginFilter", value = {"/*"}, initParams = {@WebInitParam(name = "unfilteredPaths", value = "login.jsp;failure.jsp;login")})
- public class LoginFilter implements javax.servlet.Filter {
- private FilterConfig config;
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {
- System.out.println("===LoginFilter===init===");
- config = filterConfig;
- }
- @Override
- public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
- System.out.println("===LoginFilter===doFilter===start===");
- HttpServletRequest request = (HttpServletRequest) servletRequest;
- HttpServletResponse response = (HttpServletResponse) servletResponse;
- HttpSession session = request.getSession();
- String unfilteredPaths = config.getInitParameter("unfilteredPaths");
- if (unfilteredPaths != null) {
- String[] strArray = unfilteredPaths.split(";");
- for (int i = 0; i < strArray.length; i++) {
- if (strArray[i] == null || "".equals(strArray[i])) {
- continue;
- }
- if (request.getRequestURI().indexOf(strArray[i]) != -1) {
- filterChain.doFilter(request, response);
- return;
- }
- }
- }
- if (session.getAttribute("username") != null) {
- filterChain.doFilter(request, response);
- } else {
- response.sendRedirect("login.jsp");
- }
- System.out.println("===LoginFilter===doFilter===end===");
- }
- @Override
- public void destroy() {
- System.out.println("===LoginFilter===destroy===");
- }
- }
EncodingFilter.java
- package com.pumpkin.filter;
- import com.sun.net.httpserver.Filter;
- import com.sun.net.httpserver.HttpExchange;
- import javax.servlet.*;
- import javax.servlet.annotation.WebFilter;
- import javax.servlet.annotation.WebInitParam;
- import java.io.IOException;
- @WebFilter(filterName = "Filter0_EncodingFilter", value = {"/*"}, initParams = {@WebInitParam(name = "charset", value = "UTF-8")})
- public class EncodingFilter implements javax.servlet.Filter{
- private FilterConfig config;
- @Override
- public void init(FilterConfig filterConfig) throws ServletException {
- System.out.println("===EncodingFilter===init===");
- config = filterConfig;
- }
- @Override
- public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
- System.out.println("===EncodingFilter===doFilter===start===");
- String charset = config.getInitParameter("charset");
- if (charset == null) {
- charset = "UTF-8";
- }
- servletRequest.setCharacterEncoding(charset);
- filterChain.doFilter(servletRequest,servletResponse);
- System.out.println("===EncodingFilter===doFilter===end===");
- }
- @Override
- public void destroy() {
- System.out.println("===EncodingFilter===destroy===");
- }
- }
LoginServlet.java
- @WebServlet(name = "LoginServlet",urlPatterns = "/login")
这样的配置等同web.xml中的配置
- <servlet>
- <servlet-name>LoginServlet</servlet-name>
- <servlet-class>com.pumpkin.servlet.LoginServlet</servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>LoginServlet</servlet-name>
- <url-pattern>/login</url-pattern>
- </servlet-mapping>
LoginFilter.java
- @WebFilter(filterName = "Filter1_LoginFilter", value = {"/*"}, initParams = {@WebInitParam(name = "unfilteredPaths", value = "login.jsp;failure.jsp;login")})
这样的配置等同web.xml中的配置
- <filter>
- <filter-name>loginFilter</filter-name>
- <filter-class>com.pumpkin.filter.LoginFilter</filter-class>
- <init-param>
- <param-name>unfilteredPaths</param-name>
- <param-value>login.jsp;failure.jsp;login</param-value>
- </init-param>
- </filter>
- <filter-mapping>
- <filter-name>loginFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
EncodingFilter.java
- @WebFilter(filterName = "Filter0_EncodingFilter", value = {"/*"}, initParams = {@WebInitParam(name = "charset", value = "UTF-8")})
这样的配置等同web.xml中的配置
- <filter>
- <filter-name>EncodingFilter</filter-name>
- <filter-class>com.pumpkin.filter.EncodingFilter</filter-class>
- <init-param>
- <param-name>charset</param-name>
- <param-value>UTF-8</param-value>
- </init-param>
- </filter>
- <filter-mapping>
- <filter-name>EncodingFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
Servlet3.0过滤器执行顺序:
Servlet3.0之前Filter过滤的顺序是由用户在web.xml中配置的顺序决定的,如我们的程序会先执行LoginFilter,再执行encodingFilter。
在3.0之后新增@WebFilter注解,当使用注解配置多个Filter时,用户无法控制其执行顺序,此时Filter过滤的顺序是按照Filter的类名来控制的,按自然排序的规则。LoginFilter.java 和 EncodingFilter.java 这两个文件里面分别是“用户登录过滤器”和“字符集过滤器”,因为这两个文件的首字母E排L之前,导致每次执行的时候都是先执行“字符集过滤器”再执行“用户登录过滤器”,所以我们现在修改两个文件的名称分别为
Filter0_EncodingFilter.java
Filter1_LoginFilter.java
这样就能先执行“用户登录过滤器”再执行“字符集过滤器”。