【过滤器入门】学会使用过滤器,为你的web项目添砖加瓦

简介: 到这里我们对Java Web的学习也到尾声了,本专栏关于Java Web的知识也是非常全的。

前言


到这里我们对Java Web的学习也到尾声了,本专栏关于Java Web的知识也是非常全的,如果有这方面的需求可以关注一下本专栏。


接下来我们来学习几个辅助性质的技术,首先来学习过滤器。


什么是过滤器?

过滤器实际上就是对web资源进行拦截,做一些处理后再交给下一个过滤器或servlet处理。


通常都是用来拦截request进行处理的,也可以对返回的response进行拦截处理。


对于过滤器:


(1)过滤器(Filter)是J2EE Servlet模板下的组件。

(2)Filter的作用是对URL进行统一的拦截处理。

(3)Filter通常用于应用程序层面进行全局处理。

大概流程图如下:

image.png


开发一个过滤器

要只要我们开发一个过滤器都需要经过一下三个步骤:


(1)任何过滤器都要实现javax.servlet.Filter接口。

(2)在Filter接口的do Filter()方法中编写过滤器的功能代码。

(3)在web.xml中对过滤器进行配置,说明拦截URL的范围。


接下来我们就来演示开发一个简单的过滤器。


首先创建写一个过滤器先实现Filter接口,然后重写里面的do Filter()方法。

我们第一个过滤器:

public class MyFirstFilter implements Filter{
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    throws IOException, ServletException {
  // TODO Auto-generated method stub
  System.out.println("过滤器已生效");
  chain.doFilter(request, response);
  }
}



在web.xml中进行配置


(1)filter标签用于说明哪个类是过滤器,并在应用启动时自动加载.

(2)filter-mapping标签用于说明过滤器对URL应用的范围,要点有二:

filter-name 过滤器名称与filter.filter-name保持一致
url-pattern 说明过滤器作用范围, /*代表对所有URL进行过滤
  MyFirstFilter
  com.imooc.filter.MyFirstFilter
  MyFirstFilter
  /*


我们再写一个servlet进行测试:

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
  private static final long serialVersionUID = 1L;
  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  response.setContentType("text/html ; charset=utf-8");
  response.getWriter().println("你好,世界!");
  }



输出:

在浏览器对servlet进行访问

image.png

看控制台

image.png

说明我们在do Filter()中设置的处理语句成功生效了。


我们除了在web.xml中配置还可以使用注解形式配置,如:

@WebFilter(filterName="MyFirstFilter", urlPatterns="/*")
public class MyFirstFilter implements Filter{
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    throws IOException, ServletException {
  // TODO Auto-generated method stub
  System.out.println("过滤器已生效");
  chain.doFilter(request, response);
  }
}



看起来是非常简单的,也是配置成功了。


过滤器的生命周期

我们在实现Filter接口之后,其实需要重写的方法有三个,如下:

public class MyFirstFilter implements Filter{
  @Override
  public void destroy() {
  }
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    throws IOException, ServletException {
  }
  @Override
  public void init(FilterConfig arg0) throws ServletException {
  }
}


这三个函数也构成了过滤器的生命周期。它们的作用分别是:


(1)Filter.init():过滤器初始化工作。

(2)Filter.doFilter():进行过滤处理。

(3)Filter.destroy():销毁过滤器。

image.png


我们可以把之前的案例中的过滤器进行更改,如下:

public class MyFirstFilter implements Filter{
  @Override
  public void destroy() {
  // TODO Auto-generated method stub
  System.out.println("过滤器已被销毁");
  }
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    throws IOException, ServletException {
  // TODO Auto-generated method stub
  System.out.println("过滤器已生效");
  chain.doFilter(request, response);
  }
  @Override
  public void init(FilterConfig arg0) throws ServletException {
  // TODO Auto-generated method stub
  System.out.println("过滤器初始化成功");
  }
}


看一下过滤器的处理过程:

在启动Tomcat之后,先是初始化成功,然后在访问url之后过滤器生效了。

image.pngimage.png

最后在关闭Tomcat之后,显示销毁过滤器了。

image.png

过滤器的特征:


(1) 过滤器对象在Web应用启动时被创建且全局唯一

(2)唯一的过滤器对象在并发环境中采用“多线程”提供服务


过滤器参数化

过滤器参数化分为两部分:


(1)过滤器为了增强灵活性,允许配置信息放在web.xml中。

(2)在web.xml中配置设置过滤器参数


接下来我们做一个字符集过滤器来进行演示:


Web输出是中文的话会出现中文乱码问题,对于解决中文乱码问题我们有以下几个办法:


(1)GET请求:在servlet.xml中增加URIEncoding = "UTF-8"。

(2)POST请求:使用request.setCharacterEncoding("UTF-7");

(3)响应:response.setContentType("text/html;charset=UTF-8");


如果我们做的是个大的项目的话我们就需要给多个Servlet去添加这些东西,其实我们只需要添加一个过滤器提前去解决这些问题就行了。不必去一个一个添加处理。


我们写一个字符集过滤器,但是有时根据用户不同我们使用的字符集编码又不是统一的,需要经常进行更改,如果直接在过滤器中进行更改的话,我们每一次更改都需要整个项目重新进行编译处理,重新发布。


这样十分麻烦,我们直接在web.xml中把字符集设置成参数,在web.xml中更改,由于这是一个解释型语言,所以不需要重新编译就很方便。


如下:

image.png

public class CharacterEncodingFilter implements Filter {
  //设置所用的字符集编码,值通过过滤器获取
  private String encoding;
  @Override
  public void destroy() {
  // 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;
  req.setCharacterEncoding(encoding);
  HttpServletResponse res = (HttpServletResponse)response;
  res.setContentType("text/html; charset = " + encoding);
  chain.doFilter(request, response);
  }
  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
  // TODO Auto-generated method stub
  encoding = filterConfig.getInitParameter("encoding");
  System.out.println("encoding:" + encoding);
  }
}
在web.xml中进行配置并且设置参数:
   CharacterEncodingFilter
   com.imooc.filter.CharacterEncodingFilter
    encoding
    utf-8
  CharacterEncodingFilter
  /*



非常简单,但是非常实用。


设置过滤范围

在前面简略的提到了url-pattern 说明过滤器作用范围, /*代表对所有URL进行过滤。接下来我们就具体来学习在url-pattern标签中设置过滤器生效的范围。


url-pattern常用写法


(1)/index.jsp:执行资源精准匹配

(2)/servlet/*:以前缀进行模式匹配

(3)*.jsp:以后缀进行模式匹配


例如*.jsp,就是把url后缀为*.jsp的所有url进行拦截下来通过所绑定的这个过滤器处理。其他类同!


过滤链

我们在写一个web项目的时候,使用的到过滤器通常不止一个,这些多个过滤器就构成了一个过滤链,如下:


我们在开发过滤链的时候需要注意:


(1)每一个过滤器应具有单独职能。

(2)过滤器的执行顺序以web.xml中的顺序为准。

(3)调用chain.doFilter()将请求向后传递。


尤其注意chain.doFilter(),我们之前在doFilter方法中的最后一步都是chain.doFilter(request, response),就是代表将请求传向下一个过滤器或者servlet。


结语

过滤器内容比较少,但是过滤器比较常用所以还是要多多理解练习!


相关文章
|
9天前
|
前端开发
【前端web入门第四天】02 CSS三大特性+背景图
本文详细介绍了CSS的三大特性:继承性、层叠性和优先级,并深入讲解了背景图的相关属性,包括背景属性、背景图的平铺方式、位置设定、缩放、固定以及复合属性。其中,继承性指子元素自动继承父元素的文字控制属性;层叠性指相同属性后定义覆盖前定义,不同属性可叠加;优先级涉及选择器权重,包括行内样式、ID选择器等。背景图部分则通过具体示例展示了如何设置背景图像的位置、大小及固定方式等。
235 91
|
9天前
|
前端开发
【前端web入门第四天】01 复合选择器与伪类选择器
本文档详细介绍了CSS中的复合选择器与伪类选择器。复合选择器包括后代选择器、子代选择器、并集选择器和交集选择器,能够更精确地定位和样式化元素。后代选择器用于选中某元素的所有后代,子代选择器仅选中直接子元素。并集选择器可为多个标签设置相同样式,而交集选择器则选中同时满足多个条件的元素。此外,还介绍了伪类选择器,如鼠标悬停效果和超链接的不同状态。
45 32
【前端web入门第四天】01 复合选择器与伪类选择器
|
8天前
|
前端开发
【前端web入门第五天】03 清除默认样式与外边距问题【附综合案例产品卡片与新闻列表】
本文档详细介绍了CSS中清除默认样式的方法,包括清除内外边距、列表项目符号等;探讨了外边距的合并与塌陷问题及其解决策略;讲解了行内元素垂直边距的处理技巧;并介绍了圆角与盒子阴影效果的实现方法。最后通过产品卡片和新闻列表两个综合案例,展示了所学知识的实际应用。
22 11
|
8天前
|
前端开发
|
8天前
|
弹性计算 前端开发 容器
【前端web入门第六天】02 flex布局
Flex布局是一种现代CSS布局模式,通过给父元素设置`display: flex`,其子元素可自动挤压或拉伸。它包含弹性容器和弹性盒子,主轴默认为水平方向,侧轴为垂直方向。主轴对齐方式由`justify-content`属性控制,侧轴对齐方式包括`align-items`(针对所有子元素)和`align-self`(针对单个子元素)。修改主轴方向使用`flex-direction`属性,`flex`属性用于控制子元素在主轴上的伸缩比例。此外,`flex-wrap`属性允许子元素换行,而`align-content`属性则定义多行对齐方式。
|
8天前
|
前端开发
【前端web入门第五天】01 结构伪类选择器与伪元素选择器
本文介绍了CSS中的结构伪类选择器和伪元素选择器。结构伪类选择器如`nth-child`可根据元素结构关系进行选择,例如将列表中首个`<li>`元素背景设为绿色。伪元素选择器用于创建装饰性内容。
|
8天前
|
SQL 安全 数据库
从入门到精通:Python Web安全守护指南,SQL注入、XSS、CSRF全防御!
【9月更文挑战第13天】在开发Python Web应用时,安全性至关重要。本文通过问答形式,详细介绍如何防范SQL注入、XSS及CSRF等常见威胁。通过使用参数化查询、HTML转义和CSRF令牌等技术,确保应用安全。附带示例代码,帮助读者从入门到精通Python Web安全。
29 6
|
8天前
|
前端开发
【前端web入门第五天】02 盒子模型基础
本文档详细介绍了CSS中的盒子模型及其组成部分,包括内容区域、内边距、边框线和外边距。通过具体示例展示了如何设置边框线、内边距及外边距,并解释了尺寸计算方法和版心居中的技巧。内容丰富,示例清晰,有助于理解盒子模型在网页布局中的应用。
|
8天前
|
前端开发
【前端web入门第六天】01 CSS浮动
这是关于CSS布局第六天学习目标的介绍,主要解决多个`<div>`标签在同一行显示的问题,即一个在左边,另一个在右边。文中介绍了标准流、浮动及flex布局的概念,重点推荐使用flex布局。文章详细讲解了浮动的基本使用、布局技巧及清除浮动的方法,包括额外标签法、单伪元素法、双伪元素法和`overflow`隐藏法,并提供了示例代码帮助理解。
|
8天前
|
前端开发
前端web入门第四天】03 显示模式+综合案例热词与banner效果
本文档介绍了HTML中标签的三种显示模式:块级元素、行内元素与行内块元素,并详细解释了各自的特性和应用场景。块级元素独占一行,宽度默认为父级100%,可设置宽高;行内元素在同一行显示,尺寸由内容决定,设置宽高无效;行内块元素在同一行显示,尺寸由内容决定,可设置宽高。此外,还提供了两个综合案例,包括热词展示和banner效果实现,帮助读者更好地理解和应用这些显示模式。