简介

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

过滤器可以拦截请求和响应,,操作请求和响应中的数据,,控制是否允许访问目标资源,,url级别的拦截 (粗粒度)。

原理

一个过滤器

首先在HttpServletRequest到达 Servlet 之前,拦截客户的HttpServletRequest 。根据需要检查HttpServletRequest,也可以修改HttpServletRequest 头和数据。
然后在HttpServletResponse到达客户端之前,拦截HttpServletResponse 。根据需要检查HttpServletResponse,也可以修改HttpServletResponse头和数据。

基本应用

1,创建一个Filter

  1. public class Filter1 implements Filter {
  2.  
  3. @Override
  4. public void init(FilterConfig filterConfig) throws ServletException {
  5. }
  6.  
  7. @Override
  8. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  9. throws IOException, ServletException {
  10. // 为了调用子类的方法
  11. HttpServletRequest httpServletRequest = (HttpServletRequest) request;
  12. System.out.println("***** 执行过滤器1 ... ...拦截路径: " + httpServletRequest.getRequestURI());
  13. // 允许访问目标资源,简称 放行
  14. chain.doFilter(httpServletRequest, response);
  15. }
  16.  
  17. @Override
  18. public void destroy() {
  19. }
  20.  
  21. }

2,web.xml配置

  1. <!-- 注册过滤器 -->
  2. <filter>
  3. <filter-name>filter1</filter-name>
  4. <filter-class>com.test.web.filter.Filter1</filter-class>
  5. <!-- 配置当前过滤器的配置信息 -->
  6. <init-param>
  7. <param-name>safeNum</param-name>
  8. <param-value>10</param-value>
  9. </init-param>
  10. </filter>
  11. <!-- 映射过滤器需要拦截的路径 -->
  12. <filter-mapping>
  13. <filter-name>filter1</filter-name>
  14. <url-pattern>/hello.jsp</url-pattern>
  15. <url-pattern>/HelloServlet</url-pattern>
  16. </filter-mapping>

过滤器链(多个过滤器共同拦截)

注意:我们下面的两个过滤器都拦截了同样的路径,先后顺序是由映射决定的,而不是注册顺序,也就是说下面这两个过滤器先执行的是filter2而不是filter1

  1. <!-- 注册过滤器 -->
  2. <filter>
  3. <filter-name>filter1</filter-name>
  4. <filter-class>com.test.web.filter.Filter1</filter-class>
  5. </filter>
  6. <filter>
  7. <filter-name>filter2</filter-name>
  8. <filter-class>com.test.web.filter.Filter2</filter-class>
  9. </filter>
  10. <!-- 映射过滤器需要拦截的路径 -->
  11. <filter-mapping>
  12. <filter-name>filter2</filter-name>
  13. <url-pattern>/hello.jsp</url-pattern>
  14. <url-pattern>/HelloServlet</url-pattern>
  15. </filter-mapping>
  16. <filter-mapping>
  17. <filter-name>filter1</filter-name>
  18. <url-pattern>/hello.jsp</url-pattern>
  19. <url-pattern>/HelloServlet</url-pattern>
  20. </filter-mapping>

生命周期

如下所示,1:实例化  2,初始化  3,拦截工作  4,销毁

  1. public class Filter2 implements Filter {
  2.  
  3. public Filter2() {
  4. System.out.println("----------- 1 执行Filter2的构造方法");
  5. }
  6.  
  7. public void init(FilterConfig fConfig) throws ServletException {
  8. System.out.println("----------- 2 执行Filter2的初始化方法");
  9. }
  10.  
  11. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  12. throws IOException, ServletException {
  13. // 为了调用子类的方法
  14. HttpServletRequest httpServletRequest = (HttpServletRequest) request;
  15. System.out.println("----------- 3 执行Filter2的执行拦截的方法 , 拦截路径:" + httpServletRequest.getRequestURI());// 放行
  16. chain.doFilter(request, response);
  17. }
  18.  
  19. public void destroy() {
  20. System.out.println("----------- 4 执行Filter2的销毁的方法 ");
  21. }
  22.  
  23. }

过滤器拦截方式

​ 1 直接请求(默认)

​ 2 请求转发(forward)

​ 3 错误页面跳转(error)

​ 4 引入其他页面(include)

如果你修改拦截方式,需要在web.xml中 通过 dispatcher标签指定。

  1. <filter>
  2. <display-name>Filter2</display-name>
  3. <filter-name>Filter2</filter-name>
  4. <filter-class>com.test.web.filter.Filter2</filter-class>
  5. <!-- 配置当前过滤器的配置信息 -->
  6. <init-param>
  7. <param-name>safeNum</param-name>
  8. <param-value>10</param-value>
  9. </init-param>
  10. </filter>
  11. <filter-mapping>
  12. <filter-name>Filter2</filter-name>
  13. <url-pattern>/hello.jsp</url-pattern>
  14. <!-- 配置拦截jsp的方式: 请求转发 -->
  15. <dispatcher>FORWARD</dispatcher>
  16. <!-- 增加拦截方式: 直接请求 -->
  17. <dispatcher>REQUEST</dispatcher>
  18. </filter-mapping>
  19. <filter-mapping>
  20. <filter-name>Filter2</filter-name>
  21. <url-pattern>/HelloServlet</url-pattern>
  22. </filter-mapping>

案例演示一:解决post方式获取参数乱码和浏览器乱码

Filter:

  1. public class EncodingFilter implements Filter {
  2.  
  3. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  4. throws IOException, ServletException {
  5. // 1 解决获取参数中文乱码(post)
  6. request.setCharacterEncoding("utf-8");
  7. // 2 解决浏览器出现的中文乱码
  8. response.setContentType("text/html;charset=utf-8");
  9. chain.doFilter(request, response);
  10. }
  11.  
  12. public void destroy() {
  13. }
  14.  
  15. public void init(FilterConfig fConfig) throws ServletException {
  16. }
  17.  
  18. }

web.xml:

  1. <filter>
  2. <display-name>EncodingFilter</display-name>
  3. <filter-name>EncodingFilter</filter-name>
  4. <filter-class>com.test.web.filter.EncodingFilter</filter-class>
  5. </filter>
  6. <filter-mapping>
  7. <filter-name>EncodingFilter</filter-name>
  8. <url-pattern>/*</url-pattern>
  9. </filter-mapping>

案例演示二:统一解决get和post获取参数乱码

Filter:

  1. public class GenericEncodingFilter implements Filter {
  2.  
  3. public void destroy() {
  4. }
  5.  
  6. public void init(FilterConfig fConfig) throws ServletException {
  7. }
  8.  
  9. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  10. throws IOException, ServletException {
  11. // 为了能够使用 子类的方法, 向下转型
  12. HttpServletRequest httpServletRequest = (HttpServletRequest) request;
  13. // 对子类获取参数的方法进行增强: 包装
  14. HttpServletRequest myRequest = new MyRequest(httpServletRequest);
  15. // 放行
  16. chain.doFilter(myRequest, response);
  17. }
  18.  
  19. class MyRequest extends HttpServletRequestWrapper {
  20.  
  21. private HttpServletRequest request;
  22.  
  23. // 标识: 表示map是否处理过
  24. private boolean isUpdate = false; // 表示没有处理
  25.  
  26. public MyRequest(HttpServletRequest request) {
  27. super(request); // 注意: 这行代码不能丢失
  28.  
  29. this.request = request;
  30. }
  31.  
  32. @Override
  33. public Map<String, String[]> getParameterMap() {
  34. // 1 获取请求方式
  35. String method = request.getMethod();
  36. // 2 判断
  37. if ("post".equalsIgnoreCase(method)) {
  38. // 2.1 如果是post方式, 设置请求编码集, 返回map即可
  39. try {
  40. request.setCharacterEncoding("utf-8");
  41. return request.getParameterMap(); // 结束当前方法
  42. } catch (UnsupportedEncodingException e) {
  43. e.printStackTrace();
  44. }
  45. } else if ("get".equalsIgnoreCase(method)) {
  46. // 2.2 如果是get方式
  47. // 2.2.1 获取map(没有处理)
  48. Map<String, String[]> parameterMap = request.getParameterMap();
  49. // 2.2.2 遍历map中的值, 使用先编码,再解码 解决乱码问题
  50. if (parameterMap != null && isUpdate==false) { // 如果map没有处理过且不为null,才会被处理
  51. for (Entry<String, String[]> en : parameterMap.entrySet()) {
  52. String[] valArr = en.getValue(); // 数组是一个引用(地址)
  53. for (int i = 0; i < valArr.length; i++) { // 注意:
  54. // 这里不能使用增强for循环
  55. try {
  56. valArr[i] = new String(valArr[i].getBytes("iso-8859-1"), "utf-8");
  57. } catch (UnsupportedEncodingException e) {
  58. e.printStackTrace();
  59. }
  60. }
  61. }
  62. // 处理完map需要将状态修改为true
  63. isUpdate = true;
  64. }
  65. // 2.2.3 返回map(处理过)
  66. return parameterMap;
  67. }
  68. return super.getParameterMap();
  69. }
  70.  
  71. // 改造获取非多选的值
  72. @Override
  73. public String getParameter(String name) {
  74. // 1 获取已经处理好的map
  75. Map<String, String[]> parameterMap = this.getParameterMap();
  76. // 2 从map中获取正确的值
  77. String[] valArr = parameterMap.get(name);
  78. // 3 判断
  79. if (valArr != null) {
  80. return valArr[0];
  81. } else {
  82. return null;
  83. }
  84. }
  85.  
  86. @Override
  87. public String[] getParameterValues(String name) {
  88. // 1 获取已经处理好的map
  89. Map<String, String[]> parameterMap = this.getParameterMap();
  90. // 2 从map中获取正确的值
  91. String[] valArr = parameterMap.get(name);
  92. return valArr;
  93. }
  94.  
  95. }
  96.  
  97. }

web.xml:

  1. <filter>
  2. <display-name>GenericEncodingFilter</display-name>
  3. <filter-name>GenericEncodingFilter</filter-name>
  4. <filter-class>com.test.web.filter.GenericEncodingFilter</filter-class>
  5. </filter>
  6. <filter-mapping>
  7. <filter-name>GenericEncodingFilter</filter-name>
  8. <url-pattern>/*</url-pattern>
  9. </filter-mapping>

java Web 过滤器Filter详解的更多相关文章

  1. java web之Filter详解

    java web之Filter详解 2012-10-20 0 个评论 作者:chenshufei2 收藏 我要投稿 .概念: Filter也称之为过滤器,它是Servlet技术中比较激动人心的技术,W ...

  2. java web.xml配置详解(转)

    源出处:java web.xml配置详解 1.常规配置:每一个站的WEB-INF下都有一个web.xml的设定文件,它提供了我们站台的配置设定. web.xml定义: .站台的名称和说明 .针对环境参 ...

  3. 《Tomcat与Java Web开发技术详解》思维导图

    越想构建上层建筑,就越觉得底层基础很重要.补课系列. 书是良心书,就是太基础了,正适合补课. [纯文字版] Tomcat与Java Web开发技术详解 Servlet Servlet的生命周期 初始化 ...

  4. Java web.xml 配置详解

    在项目中总会遇到一些关于加载的优先级问题,近期也同样遇到过类似的,所以自己查找资料总结了下,下面有些是转载其他人的,毕竟人家写的不错,自己也就不重复造轮子了,只是略加点了自己的修饰. 首先可以肯定的是 ...

  5. java web.xml配置详解

    1.启动一个WEB项目的时候,WEB容器会去读取它的配置文件web.xml,读取<listener>和<context-param>两个结点. 2.紧急着,容创建一个Servl ...

  6. Java Web(一) Servlet详解!!

    这篇文章到上一篇,距离的有点遥远呀,隔了大概有两个月把,中间在家过了个年,哈哈~ 现在重新开始拾起,最近在看一本个人觉得很棒的书,<Java Web 整合开发王者归来>,现在写的这一系列基 ...

  7. Servlet中的过滤器Filter详解

    加载执行顺序 context-param->listener->filter->servlet web.xml中元素执行的顺序listener->filter->stru ...

  8. (转)Java Web(一) Servlet详解!!

    https://www.cnblogs.com/whgk/p/6399262.html 这篇文章到上一篇,距离的有点遥远呀,隔了大概有两个月把,中间在家过了个年,哈哈~ 现在重新开始拾起,最近在看一本 ...

  9. Java Web开发之详解JSP

    JSP作为Java Web开发中比较重要的技术,一般当作视图(View)的技术所使用,即用来展现页面.Servlet由于其本身不适合作为表现层技术,所以一般被当作控制器(Controller)所使用, ...

随机推荐

  1. C++11 Lambda表达式(匿名函数)

    http://www.cnblogs.com/RainyBear/p/5733399.html http://blog.163.com/lvan100@yeah/blog/static/6811721 ...

  2. 人生苦短之我用Python篇(paramiko模块)

    该模块机遇SSH用于连接远程服务器并执行相关操作 基于用户名密码连接: import paramiko # 创建SSH对象 ssh = paramiko.SSHClient() # 允许连接不在kno ...

  3. 关于Bootstrap table的回调onLoadSuccess()和onPostBody()使用小结

    关于Bootstrap table的回调onLoadSuccess()和onPostBody()使用小结 Bootstrap table 是一款基于 Bootstrap 的 jQuery 表格插件, ...

  4. kali学习

    kali视频学习 第二周 kali视频(1-5) 1.kali安装 2.基本配置 vmtools安装过程. 3.安全渗透测试一般流程 4.信息搜集之GoogleHack 5.信息搜集之目标获取 第三周 ...

  5. jQuery使用prop设置checkbox全选、反选

    $(function(){     var checkbox = $("input[type='checkbox']");     //全选     $('#select-all' ...

  6. 剑指offer-第二章数据结构(数组,字符串,链表,树,栈与队列)及例题

    一.数组(最简单的数据结构) 定义:占据一块连续内存并按照顺序存储数据.创建时先指定大小,分配内存. 优点:时间效率高.实现简单的hash(下标为key,对应的数据为value) 缺点:空间效率差.如 ...

  7. HTML服务器控件与Web服务器控件

    asp.net之所以现在开发方便和快捷,关键是它有一组强大的控件库,包括web服务器控件,web用户控件,web自定义控件,html服务器控件和html控件等.这里主要整理一下html控件.html服 ...

  8. sublime text3 中设置默认浏览器,并且设置快捷键

    1.打开packageControl   对应快捷键  command + shift + p 2.输入install package 3.安装插件 SideBarEnhancements 4.安装了 ...

  9. openfaas 私有镜像配置

    备注: 此项目是使用nodejs  生成唯一id 的\ 预备环境 docker harbor faas-cli openfaas k8s 1. 项目初始化 faas-cli new node --la ...

  10. 【openCV学习笔记】在Mac上配置openCV步骤详解

    (1)安装Homebrew:(需要Ruby) 注:因为snow leopard 以后已经自带Ruby了,所有可以不用自己安装Ruby. 看一下Homebrew的官网: http://mxcl.gith ...