博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
1.7(学习笔记)过滤器(Fliter)
阅读量:7052 次
发布时间:2019-06-28

本文共 8180 字,大约阅读时间需要 27 分钟。

一、过滤器(Fliter)简介

  过滤器是位于客户端与服务器之间的滤网,在访问资源时会经过一系列的过滤器,

  满足条件则放行,不满足条件的将其拦截。

  

 

  过滤器可以看做是一个特殊的Servlet,设置了过滤器及其过滤范围后,

  访问处于过滤器过滤范围的资源,会先经过滤器,如果满足过滤条件就会被过滤器放行。

  一系列过滤器的组合称为过滤链,但某一资源满处于多个过滤器的过滤范围时,

  会执行完一个过滤器后进入下一个过滤器,执行顺序和web.xml中的过滤器的配置顺序有关。

  

  过滤器不仅有过滤作用,在过滤过程中可以对调用的请求进行一些操作,

  也可以调用完资源后的响应进行一些操作。

  

二、过滤器实例

  2.1编码过滤

  不适用过滤器进行编码过滤的话,每一个页面都要设置编码格式,这样显然是不方便的。

  使用过滤器和创建Servlet差不多。

  首先我们创建一个Class,然后继承Fliter接口。

  实现里面的init,doFilter,destroy方法,其中init,destroy如无特殊需要可不进行添加或修改。

 

  主要是里面的deFilter方法,当request或response进入过滤器时,主要是指向doFilter中的内容。

  doFilter方法中携带有一个参数FilterChain chain,FiterChain中还有一个比较重要的方法:

  void javax.servlet.FilterChain.doFilter(ServletRequest request, ServletResponse response)

  //调用过滤链中下一个过滤器,如果后续没有过滤器则访问对应资源

 

  一般在Filter接口下doFilter()方法里面的FilterChain.doFilter()方法前面为请求过滤,后面为响应过滤。

  

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;public class SimpleFilter implements Filter{    @Override    public void init(FilterConfig filterConfig) throws ServletException {        // TODO Auto-generated method stub    }    @Override    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)            throws IOException, ServletException {        //请求过滤,        request.setCharacterEncoding("utf-8");      response.setCharacterEncoding("utf-8");         System.out.println("Request");        //调用过滤链中后一过滤器,如果后续没有过滤器则访问对应资源。(放行)        chain.doFilter(request, response);        //响应过滤        System.out.println("Response");    }    @Override    public void destroy() {        // TODO Auto-generated method stub    }    }

这里的过滤器并没有对资源进行过滤,而只是对请求和响应进行了编码格式的改变防止乱码问题。

这里也可以设置满足一定的条件才放行(调用chain.doFilter(.....))。

设置完过滤器后,我们还需要在web.xml中配置过滤器。

配置方法和Servlet大同小异,只是在url地址这一块和Servlet的含义不一样。

CharacterFilter
com.filter.SimpleFilter
CharacterFilter
/*

主要是url-pattern中,这里面配置的是过滤器过滤的范围,‘/*’就代表过滤器过滤范围为当前项目下所有资源。

即当前项目下所有资源的reques和respons都要设置为“utf-8”编码格式。

过滤器也可以过滤某一类文件,例如所有的jsp文件,则可以这样写“*.jsp”

这样就代表过滤器范围为该资源下所有.jps文件。

当然也可以指定过滤范围为当前项目下某一部分资源,

例如“/test/*”代表过滤器过滤范围为test文件夹下所有资源。

 

一个过滤器在web.xml中可以设置多个映射(过滤范围),

这样就可以根据自己要求灵活调整过滤范围。 

 

过滤器的执行顺序是依照web.xml中的配置来的,先经过配置在前面的过滤器,后面的依次通过。

 

LoginServlet

import java.io.IOException;import java.io.PrintWriter;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 com.util.HttpPageUtil;;public class LoginServlet extends HttpServlet {    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        PrintWriter out = response.getWriter();        String username = request.getParameter("username");      //输出HTML头部代码        HttpPageUtil.printHtmlPage(out, true);        out.println("

" + username + "李四" + "

");      //输出HTML尾部代码 HttpPageUtil.printHtmlPage(out, false); System.out.println("Servlet"); } /** * @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); }}

 

HTTPUtil

import java.io.PrintWriter;public class HttpPageUtil {    //打印HTML页面,head为True打印HTML头部代码,为false打印尾部HTML代码    public static void printHtmlPage(PrintWriter out, boolean head) {        if(head) {            out.println("\r\n" +                     "\r\n" +                     "\r\n" +                     "
\r\n" + "Insert title here\r\n" + "\r\n" + ""); }else { out.println("\r\n" + ""); } }}

 

login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>
Login
username:
password:

 

 我们来看下控制台输出的信息。

RequestServletResponse

我们来分析下整个流程:

首先进入过滤器,执行编码转换,然后输出“Request”,接着放行

执行chain.doFilter();然后进入LoginServlet中输出“Servlet”,

然后再进入过滤器中输出"Response"。

 

可以看出过滤器的执行流程,就是最开始画的图的流程,

主要注意一点chain.doFilter()前面的是对应客户端到服务器这个方向的,

后面的是chain.doFilter()后面的是服务器到客户端这个方向的。

 

  2.2登录验证。

  在WebContext目录下新建一个文件夹Page,将要访问的资源文件都放在里面。

  设置一个过滤器,过滤范围为Page文件下所有文件。如果登录则可正常访问

  资源,如果没有登录则跳转到登录界面,并且提示登录。

  

  

LgoinFilter

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{    @Override    public void init(FilterConfig filterConfig) throws ServletException {        // TODO Auto-generated method stub            }    @Override    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)            throws IOException, ServletException {        // TODO Auto-generated method stub        HttpServletRequest req = (HttpServletRequest)request;        HttpSession session = req.getSession();        String username = (String)session.getAttribute("username");        //如果Session中已有username则认为已登录,(sesson在LgoinServlet中设置)        if(username != null && ! "".equals(username)) {            System.out.println("LgoinFilterRequest");            //登录则放行            chain.doFilter(request, response);            System.out.println("LgoinFilterResponse");        }else {
//反之则重定向到登录页面 request.setAttribute("error", "未登录,无法访问资源!"); //加 / 代表绝对 前缀为localhost:8080 request.getRequestDispatcher("/login.jsp").forward(request, response); } } @Override public void destroy() { // TODO Auto-generated method stub }}

 

 

LoginServlet:

import java.io.IOException;import java.io.PrintWriter;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import com.util.HttpPageUtil;;

 

public class LoginServlet extends HttpServlet {    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        PrintWriter out = response.getWriter();        String username = request.getParameter("username");        HttpSession session = request.getSession();        session.setAttribute("username", username);        HttpPageUtil.printHtmlPage(out, true);        out.println("

" + username + "

"); HttpPageUtil.printHtmlPage(out, false); System.out.println("Servlet"); }

 

/**     * @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);    }    }

 

login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>
Login ${error}
username:
password:

可以看到没有登录时无法访问资源,登录后可以访问资源。

登录过程中在LoginServlet中创建了session并将用户名放入Session,

访问Page下的资源时过滤器会判断session中是否有用户名,

有用户名则可以访问资源,反之则不能。 

 

我们来看下能访问资源时控制台输出的信息:(session已被创建)

Request

LgoinFilterRequest
LgoinFilterResponse
Response

客户端访问服务器资源,首先request会经过第一个字符编码过滤器,执行编码格式的转换。

打印出Request,然后放行到LoginFilter过滤器,LoginFilter检测到用户已登录会放行。

由于后续没有过滤器,所以到达访问资源。到达资源后response首先通过LoginFilter

中chain.doFilter()方法后面的语句,打印出LoginFilterResponse,然后执行字符编码过滤器

后面的Response。

 

执行顺序就是按下图执行的。

 

 

参考资料:

  

转载于:https://www.cnblogs.com/huang-changfan/p/10317281.html

你可能感兴趣的文章
2k8 32bit下载
查看>>
密码需要带特殊字符
查看>>
个人收集的java精品网站
查看>>
Python多版本情况下四种快速进入交互式命令行的操作技巧
查看>>
如何在基于Bytom开发过程中集成IPFS
查看>>
后台管理,给列表页新增查询功能,所遇到的问题及感想
查看>>
GraalVM 社区版 1.0 RC15 发布,新一代高性能跨语言虚拟机
查看>>
阿里架构师眼里JVM可以说的那些事
查看>>
C#实现局部峰值查找,功能对应Matlab中的findpeaks.m
查看>>
响应式编程
查看>>
The Road to learn React书籍学习笔记(第一章)
查看>>
WPF 自定义控件的坑(蠢的:自定义控件内容不显示)
查看>>
Confluence 6 空间标识
查看>>
使用kubeadm安装Kubernetes v1.10以及常见问题解答
查看>>
Linux FTP上传脚本
查看>>
Robot Framework之pymysql数据库查询
查看>>
干货 | 机器学习没有你想的那么复杂
查看>>
PostgreSQL 10.1 手册_部分 III. 服务器管理_第 16 章 从源代码安装_16.1. 简单版
查看>>
springMVC的事务不回滚
查看>>
WPF与缓动(三) 指数缓动
查看>>