博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java Web三大组件--过滤器
阅读量:4634 次
发布时间:2019-06-09

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

参考博客:

基本概念在参考博客中,已经讲的很清楚了。这里,简单总结一下,并贴一个完整实例。

总结:

1)Filter称为过滤器。它是一个服务器端的组件。通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。

2)Filter技术主要进行对用户请求的预处理,也可以对服务器响应进行后处理。

这两种情况都属于直接访问页面(也包括直接访问Servlet),故在配置<filter-mapping>时,可以不写<dispatcher>,使用默认的REQUEST。(也可以写出来直接指定为REQUEST)

一般地,客户端提交请求信息通过HttpServletRequest到达Servlet,然后Servlet进行处理并产生响应,响应通过HttpServletResponse传递到客户端。

Filter在HttpServletRequest到达Servlet之前,拦截客户的HttpServletRequest,根据需要检查HttpServletRequest,或者修改HttpServletRequest 头和数据,称为对用户请求的预处理。

Filer在HttpServletResponse从Servlet到达客户端之前,拦截HttpServletResponse ,根据需要检查HttpServletResponse,或者修改HttpServletResponse头和数据,称为对服务器响应进行后处理。

3)Filer的生命周期:

实例化(web.xml)——>初始化(init()方法)——>过滤(doFilter()方法)——>销毁(destroy()方法)

public void init(FilterConfig filterConfig) throws ServletException;//初始化    //filter对象只会创建一次,init方法也只会执行一次    和我们编写的Servlet程序一样,Filter的创建和销毁由WEB容器负责。 web 应用程序启动时,web 容器读取web.xml配置文件,    将创建Filter 的实例对象,并调用其init方法(这个init方法中可以读取web.xml文件中过滤器的参数)完成对象的初始化功能,    从而为后续的用户请求作好拦截的准备工作。开发人员可以通过init方法的参数FilterConfig对象,获得当前filter配置信息。    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;//拦截请求    //可执行n次    这个方法完成实际的过滤操作。当客户请求访问与过滤器关联的URL的时候执行该方法。FilterChain参数的doFilter方法用于访问后续过滤器或者调用目标资源。    public void destroy();//销毁    //该方法在Filter的生命周期中仅执行一次。    Filter对象创建后会驻留在内存,当web应用移除或服务器停止时才销毁。在Web容器卸载 Filter 对象之前被调用。在这个方法中,可以释放过滤器使用的资源。

4)Filter开发步骤:

  (1)编写java类实现javax.servlet.Filter接口,并实现其doFilter方法;

  (2)在web.xml文件中对编写的filter类进行注册,并设置它所能拦截的资源。

5)Filter链:

  在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称之为一个Filter链。

  web服务器根据Filter在web.xml文件中的注册顺序,决定先调用哪个Filter,当第一个Filter的doFilter方法被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源。

6)FilterConfig接口:

用户在配置filter时,可以使用为filter配置一些初始化参数(<init-param>),当web容器实例化Filter对象,调用其init方法时,会把封装了filter初始化参数的filterConfig对象传递进来。因此开发人员在编写filter时,通过filterConfig对象的方法获取相关初始化信息。

7)在检查URI路径中的是否含有某个初始值,对于servlet来说,是指配置servlet时指定的url-pattern的值,而不是servlet类名。

8)在实现Filter的类中的doFilter()方法中,需要将传进来的ServletRequest转换为HttpServletRequest,将传进来的ServletResponse转换为HttpServletResponse,才能进行相关方法的调用。

9)过滤器的分类: 

  (1)REQUEST:当用户直接访问页面(包括用户请求的预处理和对服务器响应进行后处理)时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。 

  (2)INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
  (3)FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
  (4)ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。

贴个例子,实现两个过滤器一个判断用户是否登录然后跳转指定页面,一个用来处理乱码问题:

login.jsp:

用户名:
密码:

创建一个success.jsp用于展示跳转成功。

创建登录跳转Servlet:

package com.servlet;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;@SuppressWarnings("serial")public class DoLoginServlet extends HttpServlet {    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        this.doPost(req, resp);    }    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        String userName=req.getParameter("userName");        String password=req.getParameter("password");        System.out.println(userName);        if("张三".equals(userName)&&"123".equals(password)){            //校验通过            HttpSession session = req.getSession();            session.setAttribute("userName", userName);        //这里必须使用重定向,不能使用请求转发        //请求转发:request.getRequestDispatcher().forward()是属于FORWARD类型的过滤器,需要在配置过滤器时,写明FORWARD类型的
resp.sendRedirect("success.jsp"); }else { resp.sendRedirect("login.jsp"); } }}

 注意:

请求转发:即request.getRequestDispatcher().forward(),是一种服务器的行为,客户端只有一次请求,服务器端转发后会将请求对象保存,地址栏中的URL地址不会改变,得到响应后服务器端再将响应发给客户端;

请求重定向:即response.sendRedirect(),是一种客户端行文,从本质上讲等同于两次请求,前一次请求对象不会保存,地址栏的URL地址会改变。

请求转发与请求重定向的区别,参考博客:

 

创建第一个过滤器(解决乱码):

package com.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;public class SetEconding implements Filter {    @Override    public void destroy() {        // TODO Auto-generated method stub    }    @Override    public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)            throws IOException, ServletException {        HttpServletRequest req=(HttpServletRequest)arg0;        //解决乱码问题        req.setCharacterEncoding("UTF-8");                //别忘了放行        arg2.doFilter(arg0, arg1);    }    @Override    public void init(FilterConfig arg0) throws ServletException {        // TODO Auto-generated method stub    }}

创建第二个过滤器(是否登录):

package com.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 {   //定义一个FilterConfig,用于传递出初始化方法init()中的FilterConfig对象    private FilterConfig config=null;     @Override    public void destroy() {        // TODO Auto-generated method stub    }    @Override    public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)            throws IOException, ServletException {        HttpServletRequest req=(HttpServletRequest)arg0;        HttpServletResponse resp=(HttpServletResponse)arg1;        HttpSession session=req.getSession();                //获取配置文件中配置的初始化参数,在这里是获取不过滤页面名单        String initParam=config.getInitParameter("NotFilter");        String[] notFilterPages=initParam.split(";");             //不过滤的页面直接调用FilterChain的doFilter()方法跳转到下个过滤器或者目标资源        if(notFilterPages!=null){            for(int i=0;i

web.xml配置文件:

javaEE_filter
index.html
SetEcondingFilter
com.filter.SetEconding
SetEcondingFilter
/*
LoginFilter
com.filter.LoginFilter
NotFilter
login;doLogin
LoginFilter
/*
LoginServlet
com.servlet.DoLoginServlet
LoginServlet
/doLogin

乱码问题的解决方案:


 

乱码问题的解决代码主要有两种即使用request对象的setCharacterEncoding()方法和String的构造器方法。

例:

req.setCharacterEncoding("UTF-8");

 

userName=new String(userName.getBytes("ISO-8859-1"),"UTF-8");

 

1)使用过滤器:

在本例中,为了说明过滤器的执行顺序,而定义了两个过滤器并在配置时将处理乱码的过滤器放在了靠前的位置,但是对于处理乱码的过滤器完全可以将代码

req.setCharacterEncoding("UTF-8");

放在判断是否登录的过滤器的doFilter方法体中(最好放在方法体靠前位置,以保证过滤时先进行代码乱码的过滤)。而无需创建第二个过滤器。

2)当然,也可以使用javaBean的方式解决代码乱码问题

 

转载于:https://www.cnblogs.com/dudududu/p/8505177.html

你可能感兴趣的文章
Android 悬浮窗口
查看>>
封装了一套WeCenter的IOS SDK
查看>>
Linux 用户行为日志记录
查看>>
SpringBoot学习之启动方式
查看>>
Linux Centos 7 安装配置nginx
查看>>
Java学习笔记---字符类型
查看>>
SQL Server Extended Events 进阶 3:使用Extended Events UI
查看>>
Python3中对Dict的内存优化
查看>>
软件行业项目经理主要的职责是什么?(转)
查看>>
git笔记
查看>>
Java 内部类
查看>>
maven nexus 3 third party 构件上传
查看>>
wchar用wcout输出正常cout是?
查看>>
生成svg元素函数
查看>>
学习Modern UI for WPF
查看>>
lua单链表实现
查看>>
MySql按日期进行统计(前一天、本周、某一天)[转载]
查看>>
经常用得到的安卓数据库基类
查看>>
大智慧面试经验
查看>>
比特币脚本及交易分析 - 智能合约雏形
查看>>