过滤器(filter)helloworld

首先我们明确一点,我们只说最有用的基础部分,高级篇自己去找资料。所以,下面的内容会很简单。

HelloWorld
·学了Servlet了么?
·有时候我们想在到达Servlet之前预处理一些事情。最简单的例子就是,我们想判断访问者有没有资格看到他想看到的地址。
·那么怎么做到的呢?
先不讲概念,因为太抽象。

看个demo来了解下filter是个啥。。。


public class ViewFilter implements Filter {
    private static int count = 1;
    @Override
    public void destroy() {
        System.out.println("ViewFilter destroy");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain filterChain) throws IOException, ServletException {
        count++;
        if(count%2 == 0){
            filterChain.doFilter(request, response);
        }
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        System.out.println("ViewFilter init");
    }

}

web.xml
<filter>
    <filter-name>view_filter</filter-name>
    <filter-class>com.partner4java.web.filter.ViewFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>view_filter</filter-name>
    <url-pattern>/user/*</url-pattern>
</filter-mapping>

然后随便写个user目录下的界面访问,会发现一次显示一次不显示。

根据这个demo应该大体知道是做什么的了吧? 下面我们会围绕这个demo里面新出现的几个类进行介绍

什么是Filter?
Filter(过滤器)是Servlet规范2.3中新增的技术,其基本功能就是对Servlet容器调用Servlet的过程进行拦截,从而在Servlet进行相应处理的前后实现一些特殊的功能。

Filter的基本工作原理?
首先实现Filter接口
然后通个web.xml注册进servlet容器。(形成一道屏障)
拦截成功后,调用filterChain.doFilter(request, response)来放行,那么就可以通过你的需要来判断是否要执行这个方法。如果不想放行,你可以通过response.sendRedirect之类的方式跳转到请求的用户有权或者应该到的位置。
在一个Web应用程序中可以注册多个Filter。
如果多个Filter都对同一个Servlet请求进行拦截,会形成一个过滤器链。过滤器链会根绝web.xml里面的注册顺序挨个执行,只有当前的Filter执行了chain.doFilter(req, res),才会把请求传给下一个Filter。如果任意一个Filter没有执行chain.doFilter(req, res),请求就不能走到用户想访问的地址。

三个主要接口:
·Filter
想要成为Filter的象征,实现Filter。
·FilterChain
doFilter方法的提供者。用户定义一个代表Filter链的对象应该对外提供的方法。
·FilterConfig
用来获取ServletContext,以为在web.xml中为filter配置的初始化参数等

Filter接口:
一个Filter程序就是一个Java类,他必须实现javax.servlet.Filter接口,定义了三个方法:init(FilterConfig filterConfig)、doFilter(ServletRequest request, ServletResponse response,FilterChain chain)、destroy()
Init:和Servlet的机制基本一样。如果init方法抛出了ServletException异常,或者初始化时间超过了web容器规定的时间,将销毁本Filter对象。
doFilter:当Filter能够拦截的请求到达时,将走doFilter。
destroy:destory方法在web容器卸载filter之前执行。和init一样也是声明中只执行一次。(有人说这里可以放销毁资源的方法,本人不建议这么做,因为,我们有时是kill掉tomcat)

FilterChain接口:
用户定义一个代表Filter链的对象应该对外提供的方法。
doFilter方法用于通知Web容器把请求交给Filter链中的下一个Filter链或者Servlet。

FilterConfig接口:
用来获取ServletContext,以为在web.xml中为filter配置的初始化参数或友好名称
Web容器装载并创建一个Filter的实例对象后,接着调用该实例对象的init(FilterConfig arg0)方法,将FilterConfig对象传递给Filter对象。
FilterConfig接口定义的几个方法:
getFilterName:返回友好名称,也就是<filter-name>标签内的名称
getServletContext:返回FilterConfig对象中所包装的ServletContext对象的引用
getInitParameter:用于获取<init-param>中定义的指定名称的对应值,没有返回null
getInitParameterNames:返回上面参数的所有名称Enumeration集合对象

讲了一大堆“道理”之后,我们再详细的写个demo

Filter Demo:我们要在这个demo做的事情

示例1:各种使用
在init方法中,通过FilterConfig.getInitParameter获取指定参数的参数值
打印所有的请求头信息
在调用目标Servlet进行相应处理之前,先调用ServletRequest.getRemoteHost方法获取访问者IP,然后写入到ServletResponse中
在目标Servlet进行相应之后,获取ServletContext引用,调用getRealPath获取当前web应用程序的真实路径,然后将路径和前面的初始化参数值写入到ServletResponse中
实现步骤:
1、第一步写个类实现Filter
2、在FirstFilter中声明filterConfig、paramValue然后在init中获取赋值
3、打印我们所有的InitParameter、请求头信息
(注意,真是环境不要这么直接打印,因为Sys打印方式,可看源码)
4、在Servlet响应前后写入内容
package com.partner4java.web.filter;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.concurrent.TimeUnit;

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 FirstFilter implements Filter {
    private FilterConfig filterConfig;
    String paramValue = null;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
        paramValue = filterConfig.getInitParameter("encoding");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        // -----------------------------------------------------
        System.out.println("being InitParameter....");
        Enumeration names = filterConfig.getInitParameterNames();
        while (names.hasMoreElements()) {
            String name = (String) names.nextElement();
            System.out.println("name:" + name + " value:"
                    + filterConfig.getInitParameter(name));
        }
        System.out.println("InitParameter end...");
        // -----------------------------------------------------

        System.out.println();

        // ===================================================
        System.out.println("begin headers...");
        Enumeration headerNames = ((HttpServletRequest) request)
                .getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String headerName = (String) headerNames.nextElement();
            System.out.println("name:" + headerName + " value:"
                    + ((HttpServletRequest) request).getHeader(headerName));
        }
        System.out.println("headers end...");
        // ===================================================

        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        // 在调用目标Servlet前写入相应内容
        out.println("您的ip地址为:" + request.getRemoteHost() + "<br/>");// 注意,如果前段用了apache或者nginx进行跳转,这么是获得不到ip的

        chain.doFilter(request, response);

        // 在目标Servlet返回后写入响应内容
        out.println("<br/>名字为encoding的初始化参数为:" + paramValue);
        out.println("<br/>当前web程序的真实路径:"
                + filterConfig.getServletContext().getRealPath("/"));
    }

    @Override
    public void destroy() {
        filterConfig = null;
    }

}

5、在web.xml中注册filter
<filter>
    <filter-name>firstFiler</filter-name>
    <filter-class>com.partner4java.web.filter.FirstFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
</filter>

filter-name、filter-class是必要的;init-param是可选的;
init-param 包含param-name 、 param-value ,也就是值和名称,我们getInitParameter 用到和返回的数据。

6、映射filter
 filter-mapping用来指定我们前面的filter可以拦截到的资源:
 主要两个元素filter-name、 url-pattern用于指定对应filter标签定义的名称和拦截路径匹配;
 <servlet-name> 所拦截的servlet名称;
 还有一个高级元素dispatcher ,配置我们所拦截的请求方式
<filter-mapping>
    <filter-name>firstFiler</filter-name>
    <servlet-name>MyServlet</servlet-name>
    <url-pattern>*.jsp</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
</filter-mapping>

细说<dispatcher>:
<dispatcher>有四种选择:
1、通过正常的访问请求调用—REQUEST(默认值)
2、通过RequestDispatcher. include()方法调用--INCLUDE
3、通过RequestDispatcher. forward()方法调用--FORWARD
4、如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。—ERROR
Dispatcher可设置多个
注意:
1、<filter>和<filter-mapping>里的<filter-name>要一致
2、<servlet-name>元素是某个Servlet在web.xml文件中的注册名称,<url-pattern>元素中的访问路径的设置方式遵循Servlet的URL映射规范
3、<dispatcher>默认值REQUEST,本元素可以设置多个
4、在同一个web.xml文件中可以为同一个Filter设置多个映射,如果多个匹配拦截,doFilter就会被执行多次


来一个dispatcher为ERROR的例子:
可能这个比较难理解(下面理解有可能也是错的,只供参考)
我们的web.xml里面可以配置<error-page>标签,如:
<error-page>
    <error-code>404</error-code>
    <location>/NotFound</location>
</error-page>

这样,我们就会拦截404状态的请求,到/NotFound,我们就可以配置个ERROR级别的dispatcher:
<filter>
    <filter-name>errorFilter</filter-name>
    <filter-class>com.partner4java.web.filter.ErrorFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>errorFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>ERROR</dispatcher>
</filter-mapping>

如果你还有filter没有配置dispatcher为ERROR是不会拦截到<error-page>这个设置的。
(有时候你会莫名的感觉其他filter不是没有配置ERROR么,怎么也执行了,
有可能是你的这个ErrorFilter里加了类似代码((HttpServletResponse)response).sendRedirect("error.jsp");
就是说这个执行被其他filter拦截到了)
本demo具体代码:
package com.partner4java.web.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;

public class ErrorFilter implements Filter {
    FilterConfig filterConfig;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        System.out.println("oh,ye,抓到你了");
        ((HttpServletResponse)response).sendRedirect("error.jsp");
    }

    @Override
    public void destroy() {

    }

}

package com.partner4java.web.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;

public class HelloFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        System.out.println("I'm hellofilter!");
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {

    }

}

web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">
    <display-name></display-name>

    <filter>
        <filter-name>helloFilter</filter-name>
        <filter-class>com.partner4java.web.filter.HelloFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>helloFilter</filter-name>
        <url-pattern>*.jsp</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>helloFilter</filter-name>
        <url-pattern>/NotFound</url-pattern>
    </filter-mapping>

    <filter>
        <filter-name>errorFilter</filter-name>
        <filter-class>com.partner4java.web.filter.ErrorFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>errorFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>ERROR</dispatcher>
    </filter-mapping>

    <error-page>
        <error-code>404</error-code>
        <location>/NotFound</location>
    </error-page>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

然后随便写个error.jsp界面
现在我们随便访问一个不存在的地址:
localhost/filter_demo4/adafsafdasdfasdfa.jsp

后台打印:
I'm hellofilter!
oh,ye,抓到你了
I'm hellofilter!

第一行“I'm hellofilter!”打印是因为访问了这个地址,
第二行“oh,ye,抓到你了”是因为配置了ERROR,
第三行是因为ErrorFilter做了个jsp跳转被HelloFilter拦截到了。

如果去掉errorfilter配置:
打印一行
I'm hellofilter!
然后前台啥也不显示
@WebFilter(
        dispatcherTypes = {
                DispatcherType.REQUEST,
                DispatcherType.FORWARD,
                DispatcherType.INCLUDE
        }
                    ,
        urlPatterns = { "/*" },
        initParams = {
                @WebInitParam(name = "encoding", value = "UTF-8"),
                @WebInitParam(name = "username", value = "hello_world")
        })
public class HelloFilter implements Filter {

看起来是不是很亲切?感觉似成相识?

Filter示例2:禁用缓存
在Filter里添加
要在request获取数据之前
response.setDateHeader("Expires",-1);
response.setHeader("Cache-Control","no-cache");?
response.setHeader("Pragma","no-cache");

Filter示例3:编码
就是两个form相互提交
首先filter设置编码
request.setCharacterEncoding(encoding);
当都是post方式提交的时候没问题。
当改为get的时候就乱码了,因为request.setCharacterEncoding(encoding);对get不起作用,需要如下方式获取
String username = request.getParameter("username");
out.println(new String(username.getBytes("iso-8859-1"),"UTF-8"));
具体代码:
package com.partner4java.web.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;

public class EncodFilter implements Filter {
    private String encoding;
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        encoding = filterConfig.getInitParameter("encoding");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding(encoding);
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        
    }

}

form1.jsp
<%=request.getParameter("username") %>
<br/>
<form action="form2.jsp" method="get">
    <input type="text" name="username"/>
    <input type="submit"/>
</form>

form2.jsp
<%
    String username = request.getParameter("username");
    out.println(new String(username.getBytes("iso-8859-1"),"UTF-8"));
%>
<br/>
<form action="form1.jsp" method="post">
    <input type="text" name="username"/>
    <input type="submit"/>
</form>

web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <display-name></display-name>

    <filter>
        <filter-name>encodFilter</filter-name>
        <filter-class>com.partner4java.web.filter.EncodFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodFilter</filter-name>
        <url-pattern>*.jsp</url-pattern>
    </filter-mapping>
    

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue中的过滤器Filter)是用来处理模板中的数据的一种方式。它可以在模板中对数据进行格式化、排序、过滤等操作,使数据在渲染之前经过一定的处理。 在Vue中,你可以通过全局过滤器或局部过滤器来使用过滤器。 全局过滤器可以在整个应用中使用,而局部过滤器只能在特定的组件中使用。 下面是一个使用全局过滤器的示例: ``` // 注册全局过滤器 Vue.filter('capitalize', function(value) { if (!value) return '' value = value.toString() return value.charAt(0).toUpperCase() + value.slice(1) }) // 在模板中使用过滤器 <div> {{ message | capitalize }} </div> ``` 在上面的示例中,我们注册了一个名为"capitalize"的全局过滤器,它会将传入的字符串首字母大写。然后在模板中使用了该过滤器来处理message变量。 除了全局过滤器外,你还可以在组件中定义局部过滤器。下面是一个使用局部过滤器的示例: ``` Vue.component('my-component', { // 定义局部过滤器 filters: { lowercase: function(value) { if (!value) return '' return value.toString().toLowerCase() } }, template: ` <div> {{ message | lowercase }} </div> `, data() { return { message: 'Hello World' } } }) ``` 在上面的示例中,我们在组件的`filters`选项中定义了一个名为"lowercase"的局部过滤器,并在模板中使用了该过滤器来处理message变量。 总结起来,Vue的过滤器是一种用于对模板中的数据进行处理和格式化的机制。你可以使用全局过滤器或局部过滤器来定义和使用过滤器

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值