Tomcat内部Valve组件,与我们普通使用的Filter, Interceptor这些概念非常类似.只不过,Valve只是针对Tomcat内部的.而FilterServlet的标准, Interceptor是框架层次上的概念.

它们的工作方式都是一种责任链的传递来拦截Request, Response然后进行自定义的处理.

Valve 接口

package org.apache.catalina;

import java.io.IOException;
import javax.servlet.ServletException;
import org.apache.catalina.comet.CometEvent;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;

public interface Valve {
    Valve getNext();

    void setNext(Valve var1);

    void backgroundProcess();

    void invoke(Request var1, Response var2) throws IOException, ServletException;

    void event(Request var1, Response var2, CometEvent var3) throws IOException, ServletException;

    boolean isAsyncSupported();
}

我们可以看到,Valve接口的参数,主要也是RequestResponse,然后调用下一个Valve.

使用场景

如果我们想添加一种对同一个Tomcat下所有的应用都生效的Filter,就可以使用Valve来处理了.而Filter, Interceptor这些,都只是在某个应用或框架中使用.

例子

创建一个自定义Valve的项目.(打包成jar).

package org.emacsist.valve;

import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.valves.ValveBase;

import javax.servlet.ServletException;
import java.io.IOException;

/**
 * Created by sky on 16-7-6.
 */
public class ModifiedValve extends ValveBase {

    public void invoke(Request request, Response response) throws IOException, ServletException {
        // todo yourself logic 
        getNext().invoke(request, response);
    }
}

然后将项目打包, 然后放到Tomcat的lib目录下,然后再在conf/server.xml里配置Valve元素即可.例如:

      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">

        <!-- SingleSignOn valve, share authentication between web applications
             Documentation at: /docs/config/valve.html -->
        <!--
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->

        <!-- Access log processes all example.
             Documentation at: /docs/config/valve.html
             Note: The pattern used is equivalent to using pattern="common" -->
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log." suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />

		<Valve className="org.emacsist.valve.ModifiedValve" />

      </Host>