Head-First Servelts&JSP reading note 5

Filter

过滤器就是一个对所有的请求进行intercept(拦截),然后对请求进行相应的处理,或者servlet处理完成之后,对response进行处理等。

而这一切,servlet永远不可能知道。

Filter和Servlet的相同点

1 容器也知道Filter的API

一旦一个java类实现了Filter接口,他就正式的成为了一个过滤器,容器中它也就被注册了。

2 容器管理他们的生命周期

他们也有init和destory方法,不同的是servlet有service方法(doGet/doPost),而filter拥有的是doFileter()方法

3 他们都是被部署在DD中

一个程序可能会拥有多个filter,并且DD中配置了哪一个filter会执行,按照什么顺序执行等。

实现一个Filter

如下是一个基本的Filter。

public class BeerRequestFilter implements Filter {
    private FilterConfig fc;
    public void init(FilterConfig config) throws ServletException {
        this.fc = config;
    }
    public void doFilter(ServletRequest req,
                ServletResponse resp,
                FilterChain chain) throws ServletException, IOException {
        HttpServletRequest httpReq = (HttpServletRequest) req;
        String name = httpReq.getRemoteUser();
        if (name != null) {
            fc.getServletContext().log(“User “ + name + “ is updating”);
        }
        chain.doFilter(req, resp);
    }
    public void destroy() {
        // do cleanup stuff
    }
}

1 init方法,接受一个FilterConfig对象作为参数,一般用来初始化Filter中的FilterConfig;

2 destory方法,基本上就是一个空方法;

3 doFilter(ServletRequest req, ServletResponse res, FilterChain chain),前两个参数就是传递进来的请求和响应,而chain是Filter的过滤链。

虽然是ServletRequest,但是我们可以保证他就是一个HttpServletRequest,同理,ServletResponse也肯定是一个HttpServletResponse。

chain.doFileter(req, res);是得以下一个Filter或者是Servlet能够继续进行的原因。

从FilterConfig中能够获得到一个ServletContext对象。

DD 设定

filter中filter-name和filter-class是必须的

<filter>
    <filter-name>BeerRequest</filter-name>
    <filter-class>com.example.web.BeerRequestFilter</filter-class>
    <init-param>
        <param-name>LogFileName</param-name>
        <param-value>UserLog.txt</param-value>
    </init-param>
</filter>

filter-mapping中的filter-name是必须的,另外url-pattern或者servlet-name也是必须的

<filter-mapping>
    <filter-name>BeerRequest</filter-name>
    <url-pattern>*.do</url-pattern>
</filter-mapping>

<filter-mapping>
    <filter-name>BeerRequest</filter-name>
    <servlet-name>AdviceServlet</servlet-name>
</filter-mapping>

对response进行处理

如果想要对response进行处理的话,只需要在

chain.doFilter(req, res);后面进行即可,因为在doFilter的时候已经能够保证servlet已经被执行完成了。

wrapper

1 Filter的chain.doFilter(req, res);调用之后,request和response对象传递给下一个filter或者servlet。

2 Servlet执行它的doPost或者doGet方法之后,会跳出方法调用栈,然后filter处在栈的顶层。

3 Servlet完成之后,response会直接发送给客户端,而不是先返回给filter。

4 所以在filter中的chain.doFilter之后的代码对response的处理都太晚了

所谓的包装器就是把一个HttpServletRequest或者一个HttpServletResponse对象进行包装,其实质就是把默认的行为进行修改。

有四个Wrapper,分别为:

ServletRequestWrapper

ServletResponseWrapper

HttpServletRequestWrapper

HttpServletResponseWrapper

其中后两种用途较大,HttpServletRequestWrapper已经实现了HttpServletRequest接口了。同样HttpServletResponseWrapper实现了HttpServletResponse接口。

我们只需要把想要修改的行为进行@Override或者追加新的机能就可以了。

Head-First Servelts&JSP reading note 5

时间: 2024-10-15 09:34:28

Head-First Servelts&JSP reading note 5的相关文章

Head-First Servelts&amp;JSP reading note 4

HttpSession Http协议 Http协议是无状态的stateless,所以一个用户对服务器访问的话,不管多少次,服务器都会像第一次被访问一样.也就是说服务器不会区别用户. 一个请求过来,服务器会给一个相应,然后之间的联系就断了. Session 如何让服务器能够识别出来两个请求是来自同一个客户的呢?设置一个唯一的ID,这个ID叫做SessionId. 当服务器响应一个请求的时候,会附带着把这个sessionId放到response中,在紧接着的request的时候,会把这个sessio

Head-First Servelts&amp;JSP reading note 3

<servlet> <servlet-name>BeerParamTests</servlet-name> <servlet-class>TestInitParams</servlet-class> <init-param> <param-name>adminEmail</param-name> <param-value>[email protected]</param-value> &

thinking in java ----reading note (1)

# thinking in java 4th# reading note# victor# 2016.02.10 chapter 1 对象入门 1.1 抽象的进步    (1) 所有东西都是对象.    (2) 程序是一大堆对象的组合,对象间通过消息联系.    (3) 通过封装现有对象,可制作出新型对象.    (4) 每个对象都有一种类型(某个类的实例).    (5) 同一类的所有对象都能接受相同的消息.    1.2 对象的接口 & 1.3 实现方法的隐藏     接口规定了可对一个特定

jQueryInAction Reading Note 7.

jQuery插件命名规则 jquery.pluginName.js pluginName指代的是插件的名称,如voctrals,tlaliu或者更有意义的名称. 简化jQuery函数的参数列表 如果有一个函数有多个参数,但是并不是每一个参数都是必须的,可以把必须的参数放到前面,不必须的参数包装成一个object. 如: function complex(param, options){ var settings = $.extend( { option1 : defaultValue1, opt

jQueryInAction Reading Note 6.

这一章的前面一部分实在是无法理解,略过吧... $.noConflict() 无参数,无返回值,是用来把$符号交给其它的javascript库的. 但是并没有放弃使用jQuery的意思,jQuery仍然可以使用,并且可以把jQuery指派给另外一个别的名称,如$j,但是仍然会让人不爽. 但是如果在调用了$.noConflict()方法之后,还是想要使用$的话,可以使用一种方法,这种方法说白了就是设定一个形式参数$,而形式参数对应着的实体参数是jQuery,也就是说使用函数的方式. functio

thinking in java -----reading note(2)

# thinking in java 4th# reading note# victor# 2016.02.16 chapter 2 一切都是对象 2.1 用句柄操纵对象    使用句柄作为标识符指向一个对象.但拥有句柄并不意味着有一个对象同它连接.    例如,创建一个String句柄: String s;    此时,这里创建的是句柄,并不是对象.如果向s发一条消息,就会获得一个错误.因此,较为安全的做法是:创建一个句柄时,无论如何都进行初始化. 2.2 创建对象    通常使用 new 关

thinking in java ----reading note (3)

# thinking in java 4th# reading note# victor# 2016.03.13 chapter 3 控制程序流程 3.1 java 运算符    几乎所有运算符都只能操作"基本值类型"."=","=="和"!=" 能操作所有对象,String类支持"+"和"+=". 3.1.1 优先级    运算符的优先级决定了存在多个运算符时一个表达式个部分的计算顺序

jQueryInAction Reading Note 3.

属性和特性 操作元素属性 jQuery没有用于获取或者修改元素属性的命令.需要利用javascript,首先需要做的就是获得元素的引用. each(function) 对包装集中的各个元素,进行function操作,function有默认的参数为当前元素的位置,function具有当前对象this的引用. $("img").each(function(n){ this.alt = "this is " + n+1 + "th img, id is &quo

jQueryInAction Reading Note 5.

$(function(){ $('li:has(ul)') .click(function(event){ if (this == event.target){ if($(this).children().is(':hidden')){ $(this) .css('list-style-image', 'url(minus.gif)') .children().show(); } else { $(this) .css('list-style-image', 'url(plus.gif)') .