Tomcat5.5で全アプリに適用されるFilterを作ってみる

感想おまちしてます!

全アプリケーションで共通のFilterを作る。これはサーバ全体で同じFilterが動作するということになる。

Tomcatのクラスローダなどがでてきて結構大変だった。

スポンサーリンク

Filterを作る

これは普通に作ればいい。javax.servlet.Filterをextendsして作った。

public class CommonFilter implements Filter {

public void destroy() {
// TODO 自動生成されたメソッド・スタブ

}

public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain arg2) throws IOException, ServletException {

System.out.println("[DEBUG]doFilter start");
System.out.println("[DEBUG]doFilter execute");
System.out.println("[DEBUG]doFilter end");

arg2.doFilter(arg0, arg1);
}

public void init(FilterConfig arg0) throws ServletException {

 System.out.println("[DEBUG]doFilter init " + arg0.getServletContext().getServletContextName());

}
}

web.xmlに定義する

TOMCAT_HOME/conf/web.xmlにアプリケーション全体で使われるサーブレットやFilterの定義ができる。ssiのFilter近くに以下の記述を追加。

<filter>
<filter-name>CommonFilter</filter-name>
<filter-class>
testapp.CommonFilter
</filter-class>
</filter>

<filter-mapping>
<filter-name>CommonFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

jarファイルを配置する

TOMCAT_HOME/common/libに入れたら動く。

common/libに配置した場合

正常に起動した。

//stdout.log
[DEBUG]doFilter init Tomcat Manager Application
[DEBUG]doFilter init Tomcat Manager Application
[DEBUG]doFilter init Tomcat Simple Load Balancer Example App
[DEBUG]doFilter init JSP 2.0 Examples
[DEBUG]doFilter init Welcome to Tomcat
[DEBUG]doFilter init Servlet 2.4 Examples
[DEBUG]doFilter init Tomcat Documentation
[DEBUG]doFilter init Webdav Content Management

デプロイされているアプリの分だけFilterのinitが起動しているようだ。

注意点

他のフォルダにJarを配置したらどうなるかを調べてみた。Tomcat内のアプリケーションを、

  • Tomcat側(TOMCAT_HOME/server/webapps)
  • Webアプリ側(TOMCAT_HOME/webapps)

に分かれているのがよくわかった。

server/libに配置した場合

3つはうまく起動したみたいに見える。起動したWebアプリはTomcat側のものなので起動でき、それ以外はWebアプリ側なので、server/libを見ることができず、ClassNotFoudExceptionが発生する。

//catalina.log
2007/12/11 14:31:44 org.apache.catalina.core.StandardContext start
致命的: 以前のエラーのためにコンテキストの起動が失敗しました [/servlets-examples]
//stdout.log
[DEBUG]doFilter init Tomcat Manager Application
[DEBUG]doFilter init Tomcat Manager Application
[DEBUG]doFilter init Tomcat Simple Load Balancer Example App
//localhost.log
2007/12/11 14:36:50 org.apache.catalina.core.StandardContext filterStart
致命的: フィルタ CommonFilter の起動中の例外です
java.lang.ClassNotFoundException: testapp.CommonFilter
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1362)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1208)
at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:207)
at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:302)
at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:78)
at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:3635)
at org.apache.catalina.core.StandardContext.start(StandardContext.java:4222)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:760)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:740)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:544)
at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:920)
at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:883)
at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:492)
at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1138)
at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:311)
at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:120)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1022)
at org.apache.catalina.core.StandardHost.start(StandardHost.java:736)
at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1014)
at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
at org.apache.catalina.core.StandardService.start(StandardService.java:448)
at org.apache.catalina.core.StandardServer.start(StandardServer.java:700)
at org.apache.catalina.startup.Catalina.start(Catalina.java:552)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:295)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:433)

shared/libに配置した場合

エラー発生。catalina.log、localhost.logはserver/libに配置したときと同じ感じ。stdout.logを見る
と、server/libの場合に起動しなかったWebアプリが起動している。これらはWebアプリ側なので、shared/libを見ることができ起動
できた。

//stdout.log
[DEBUG]doFilter init JSP 2.0 Examples
[DEBUG]doFilter init Welcome to Tomcat
[DEBUG]doFilter init Servlet 2.4 Examples
[DEBUG]doFilter init Tomcat Documentation
[DEBUG]doFilter init Webdav Content Management

結果

conf/web.xmlにFilterを記述して、サーバ全体で使うFilterを定義すると、デプロイされているすべてのアプリケーションで
Filterが起動する。Tomcatには「TOMCAT_HOMR/server/webapps」と「TOMCAT_HOME/webapps」に、
デフォルトでインストールされるアプリケーションがあるので、両方から読み込める場所にFilterのつまったJarファイルを配置しなければならない。

よってこれが「common/lib」にJarを配置したら成功した理由となる。

参考:TECHSCORE Tomcatのクラスローダ